Added
Link Here
|
1 |
--- plugins/occt/module/vtkF3DOCCTReader.cxx.orig 2024-01-21 15:29:01 UTC |
2 |
+++ plugins/occt/module/vtkF3DOCCTReader.cxx |
3 |
@@ -31,14 +31,17 @@ |
4 |
#if F3D_PLUGIN_OCCT_XCAF |
5 |
#include <IGESCAFControl_Reader.hxx> |
6 |
#include <STEPCAFControl_Reader.hxx> |
7 |
+#include <Standard_Version.hxx> |
8 |
#include <TDF_ChildIterator.hxx> |
9 |
#include <TDataStd_Name.hxx> |
10 |
#include <TDocStd_Document.hxx> |
11 |
#include <XCAFApp_Application.hxx> |
12 |
-#include <XCAFDoc_ColorTool.hxx> |
13 |
#include <XCAFDoc_DocumentTool.hxx> |
14 |
#include <XCAFDoc_Location.hxx> |
15 |
#include <XCAFDoc_ShapeTool.hxx> |
16 |
+#include <XCAFPrs.hxx> |
17 |
+#include <XCAFPrs_IndexedDataMapOfShapeStyle.hxx> |
18 |
+#include <XCAFPrs_Style.hxx> |
19 |
#endif |
20 |
|
21 |
#if defined(__GNUC__) |
22 |
@@ -71,6 +74,10 @@ class vtkF3DOCCTReader::vtkInternals |
23 |
|
24 |
class vtkF3DOCCTReader::vtkInternals |
25 |
{ |
26 |
+#if F3D_PLUGIN_OCCT_XCAF |
27 |
+ using StyleMap = XCAFPrs_IndexedDataMapOfShapeStyle; |
28 |
+#endif |
29 |
+ |
30 |
public: |
31 |
//---------------------------------------------------------------------------- |
32 |
explicit vtkInternals(vtkF3DOCCTReader* parent) |
33 |
@@ -79,7 +86,11 @@ class vtkF3DOCCTReader::vtkInternals |
34 |
} |
35 |
|
36 |
//---------------------------------------------------------------------------- |
37 |
+#if F3D_PLUGIN_OCCT_XCAF |
38 |
+ vtkSmartPointer<vtkPolyData> CreateShape(const TopoDS_Shape& shape, const TDF_Label& label) |
39 |
+#else |
40 |
vtkSmartPointer<vtkPolyData> CreateShape(const TopoDS_Shape& shape) |
41 |
+#endif |
42 |
{ |
43 |
vtkNew<vtkPoints> points; |
44 |
vtkNew<vtkFloatArray> normals; |
45 |
@@ -88,32 +99,49 @@ class vtkF3DOCCTReader::vtkInternals |
46 |
vtkNew<vtkFloatArray> uvs; |
47 |
uvs->SetNumberOfComponents(2); |
48 |
uvs->SetName("UV"); |
49 |
+#if F3D_PLUGIN_OCCT_XCAF |
50 |
vtkNew<vtkUnsignedCharArray> colors; |
51 |
colors->SetNumberOfComponents(3); |
52 |
colors->SetName("Colors"); |
53 |
+#endif |
54 |
vtkNew<vtkCellArray> trianglesCells; |
55 |
vtkNew<vtkCellArray> linesCells; |
56 |
|
57 |
Standard_Integer shift = 0; |
58 |
|
59 |
+#if F3D_PLUGIN_OCCT_XCAF |
60 |
+ const StyleMap inheritedStyles = this->CollectInheritedStyles(label, shape); |
61 |
+#endif |
62 |
+ |
63 |
+ /* Mesh the whole shape. This only affect faces, edges have to be handled separately. */ |
64 |
+ BRepMesh_IncrementalMesh(shape, this->Parent->GetLinearDeflection(), |
65 |
+ this->Parent->GetRelativeDeflection(), this->Parent->GetAngularDeflection(), Standard_True); |
66 |
+ |
67 |
if (this->Parent->GetReadWire()) |
68 |
{ |
69 |
- // Add all edges to polydata |
70 |
- for (TopExp_Explorer exEdge(shape, TopAbs_EDGE); exEdge.More(); exEdge.Next()) |
71 |
+ std::vector<TopoDS_Edge> edges; |
72 |
{ |
73 |
- TopoDS_Edge edge = TopoDS::Edge(exEdge.Current()); |
74 |
+ /* add all edges to a compound to remesh them all at once */ |
75 |
+ TopoDS_Builder builder; |
76 |
+ TopoDS_Compound compound; |
77 |
+ builder.MakeCompound(compound); |
78 |
+ for (TopExp_Explorer exEdge(shape, TopAbs_EDGE); exEdge.More(); exEdge.Next()) |
79 |
+ { |
80 |
+ const TopoDS_Edge edge = TopoDS::Edge(exEdge.Current()); |
81 |
+ builder.Add(compound, edge); |
82 |
+ edges.push_back(edge); |
83 |
+ } |
84 |
+ BRepMesh_IncrementalMesh(compound, this->Parent->GetLinearDeflection(), |
85 |
+ this->Parent->GetRelativeDeflection(), this->Parent->GetAngularDeflection(), |
86 |
+ Standard_True); |
87 |
+ } |
88 |
|
89 |
+ // Add all edges to polydata |
90 |
+ for (const TopoDS_Edge& edge : edges) |
91 |
+ { |
92 |
TopLoc_Location location; |
93 |
const auto& poly = BRep_Tool::Polygon3D(edge, location); |
94 |
|
95 |
- if (poly.IsNull() || poly->Nodes().Length() <= 0) |
96 |
- { |
97 |
- // meshing |
98 |
- BRepMesh_IncrementalMesh(edge, this->Parent->GetLinearDeflection(), |
99 |
- this->Parent->GetRelativeDeflection(), this->Parent->GetAngularDeflection(), |
100 |
- Standard_True); |
101 |
- } |
102 |
- |
103 |
if (poly.IsNull()) |
104 |
{ |
105 |
continue; |
106 |
@@ -134,23 +162,29 @@ class vtkF3DOCCTReader::vtkInternals |
107 |
uvs->InsertNextTypedTuple(fn); |
108 |
} |
109 |
|
110 |
- std::vector<vtkIdType> polyline(nbV - 1); |
111 |
+ std::vector<vtkIdType> polyline(nbV); |
112 |
std::iota(polyline.begin(), polyline.end(), shift); |
113 |
linesCells->InsertNextCell(polyline.size(), polyline.data()); |
114 |
|
115 |
#if F3D_PLUGIN_OCCT_XCAF |
116 |
- if (this->ColorTool) |
117 |
+ std::array<unsigned char, 3> rgb = { 0, 0, 0 }; |
118 |
+ try |
119 |
{ |
120 |
- std::array<unsigned char, 3> rgb = { 0, 0, 0 }; |
121 |
- Quantity_Color aColor; |
122 |
- if (this->ColorTool->GetColor(edge, XCAFDoc_ColorCurv, aColor)) |
123 |
+ const auto& style = inheritedStyles.FindFromKey(edge); |
124 |
+ if (style.IsSetColorCurv()) |
125 |
{ |
126 |
- rgb[0] = static_cast<unsigned char>(255.0 * aColor.Red()); |
127 |
- rgb[1] = static_cast<unsigned char>(255.0 * aColor.Green()); |
128 |
- rgb[2] = static_cast<unsigned char>(255.0 * aColor.Blue()); |
129 |
+ Quantity_Color color = style.GetColorCurv(); |
130 |
+ rgb[0] = static_cast<unsigned char>(255.0 * color.Red()); |
131 |
+ rgb[1] = static_cast<unsigned char>(255.0 * color.Green()); |
132 |
+ rgb[2] = static_cast<unsigned char>(255.0 * color.Blue()); |
133 |
} |
134 |
- colors->InsertNextTypedTuple(rgb.data()); |
135 |
} |
136 |
+ catch (Standard_NoSuchObject&) |
137 |
+ { |
138 |
+ /* edge has no style, safe to ignore */ |
139 |
+ } |
140 |
+ |
141 |
+ colors->InsertNextTypedTuple(rgb.data()); |
142 |
#endif |
143 |
|
144 |
shift += nbV; |
145 |
@@ -165,14 +199,6 @@ class vtkF3DOCCTReader::vtkInternals |
146 |
TopLoc_Location location; |
147 |
const auto& poly = BRep_Tool::Triangulation(face, location); |
148 |
|
149 |
- if (poly.IsNull() || poly->NbTriangles() <= 0) |
150 |
- { |
151 |
- // meshing |
152 |
- BRepMesh_IncrementalMesh(face, this->Parent->GetLinearDeflection(), |
153 |
- this->Parent->GetRelativeDeflection(), this->Parent->GetAngularDeflection(), |
154 |
- Standard_True); |
155 |
- } |
156 |
- |
157 |
if (poly.IsNull()) |
158 |
{ |
159 |
continue; |
160 |
@@ -243,23 +269,32 @@ class vtkF3DOCCTReader::vtkInternals |
161 |
std::swap(cell[0], cell[2]); |
162 |
} |
163 |
trianglesCells->InsertNextCell(3, cell); |
164 |
+ } |
165 |
|
166 |
#if F3D_PLUGIN_OCCT_XCAF |
167 |
- if (this->ColorTool) |
168 |
+ std::array<unsigned char, 3> rgb = { 255, 255, 255 }; |
169 |
+ try |
170 |
+ { |
171 |
+ const auto& style = inheritedStyles.FindFromKey(face); |
172 |
+ if (style.IsSetColorSurf()) |
173 |
{ |
174 |
- std::array<unsigned char, 3> rgb = { 255, 255, 255 }; |
175 |
- Quantity_Color aColor; |
176 |
- if (this->ColorTool->GetColor(face, XCAFDoc_ColorSurf, aColor)) |
177 |
- { |
178 |
- rgb[0] = static_cast<unsigned char>(255.0 * aColor.Red()); |
179 |
- rgb[1] = static_cast<unsigned char>(255.0 * aColor.Green()); |
180 |
- rgb[2] = static_cast<unsigned char>(255.0 * aColor.Blue()); |
181 |
- } |
182 |
- colors->InsertNextTypedTuple(rgb.data()); |
183 |
+ Quantity_Color color = style.GetColorSurf(); |
184 |
+ rgb[0] = static_cast<unsigned char>(255.0 * color.Red()); |
185 |
+ rgb[1] = static_cast<unsigned char>(255.0 * color.Green()); |
186 |
+ rgb[2] = static_cast<unsigned char>(255.0 * color.Blue()); |
187 |
} |
188 |
-#endif |
189 |
} |
190 |
+ catch (Standard_NoSuchObject&) |
191 |
+ { |
192 |
+ /* face has no style, safe to ignore */ |
193 |
+ } |
194 |
|
195 |
+ for (int i = 1; i <= nbT; i++) |
196 |
+ { |
197 |
+ colors->InsertNextTypedTuple(rgb.data()); |
198 |
+ } |
199 |
+#endif |
200 |
+ |
201 |
shift += nbV; |
202 |
} |
203 |
|
204 |
@@ -271,11 +306,7 @@ class vtkF3DOCCTReader::vtkInternals |
205 |
polydata->SetLines(linesCells); |
206 |
|
207 |
#if F3D_PLUGIN_OCCT_XCAF |
208 |
- /* colors may be left empty if this->ColorTool has not been initialized */ |
209 |
- if (colors->GetSize() > 0) |
210 |
- { |
211 |
- polydata->GetCellData()->SetScalars(colors); |
212 |
- } |
213 |
+ polydata->GetCellData()->SetScalars(colors); |
214 |
#endif |
215 |
|
216 |
polydata->Squeeze(); |
217 |
@@ -283,7 +314,99 @@ class vtkF3DOCCTReader::vtkInternals |
218 |
} |
219 |
|
220 |
#if F3D_PLUGIN_OCCT_XCAF |
221 |
+ StyleMap CollectInheritedStyles(const TDF_Label& rootLabel, const TopoDS_Shape& rootShape) |
222 |
+ { |
223 |
+ StyleMap inheritedStyles; |
224 |
+ |
225 |
+ if (rootLabel.IsNull()) |
226 |
+ { |
227 |
+ return inheritedStyles; |
228 |
+ } |
229 |
+ |
230 |
+ /* collect styled shapes from the document */ |
231 |
+ StyleMap collectedStyles; |
232 |
+ XCAFPrs::CollectStyleSettings(rootLabel, TopLoc_Location(), collectedStyles); |
233 |
+ |
234 |
+ /* iterate styled shapes and collect sorted by ascending shape type depth */ |
235 |
+ const auto cmp = [](const TopoDS_Shape& a, const TopoDS_Shape& b) |
236 |
+ { return a.ShapeType() > b.ShapeType(); }; |
237 |
+ std::multimap<TopoDS_Shape, XCAFPrs_Style, decltype(cmp)> styledShapes(cmp); |
238 |
+ |
239 |
+ const TopAbs_ShapeEnum leafType = this->Parent->GetReadWire() ? TopAbs_EDGE : TopAbs_FACE; |
240 |
+ for (StyleMap::Iterator iter(collectedStyles); iter.More(); iter.Next()) |
241 |
+ { |
242 |
+ const TopoDS_Shape& shape = iter.Key(); |
243 |
+ if (shape.ShapeType() <= leafType) |
244 |
+ { |
245 |
+ styledShapes.insert({ shape, iter.Value() }); |
246 |
+ } |
247 |
+ } |
248 |
+ |
249 |
+ /* pass down each parent style props to descendent edge/face leaves */ |
250 |
+ const auto passDownToLeaves = [&](TopAbs_ShapeEnum type) |
251 |
+ { |
252 |
+ for (const auto& styledShape : styledShapes) |
253 |
+ { |
254 |
+ for (TopExp_Explorer iter(styledShape.first, type); iter.More(); iter.Next()) |
255 |
+ { |
256 |
+ try |
257 |
+ { |
258 |
+ this->PassDownStyleProps( |
259 |
+ styledShape.second, inheritedStyles.ChangeFromKey(iter.Current())); |
260 |
+ } |
261 |
+ catch (Standard_NoSuchObject&) |
262 |
+ { |
263 |
+ inheritedStyles.Add(iter.Current(), styledShape.second); |
264 |
+ } |
265 |
+ } |
266 |
+ } |
267 |
+ }; |
268 |
+ |
269 |
+ passDownToLeaves(TopAbs_FACE); |
270 |
+ |
271 |
+ if (this->Parent->GetReadWire()) |
272 |
+ { |
273 |
+ passDownToLeaves(TopAbs_EDGE); |
274 |
+ } |
275 |
+ |
276 |
+ /* pass down default style (if any) to all leaves */ |
277 |
+ try |
278 |
+ { |
279 |
+ const XCAFPrs_Style& defaultStyle = collectedStyles.FindFromKey(rootShape); |
280 |
+ for (StyleMap::Iterator iter(inheritedStyles); iter.More(); iter.Next()) |
281 |
+ { |
282 |
+ XCAFPrs_Style style = iter.Value(); |
283 |
+ this->PassDownStyleProps(defaultStyle, style); |
284 |
+ } |
285 |
+ } |
286 |
+ catch (Standard_NoSuchObject&) |
287 |
+ { |
288 |
+ /* root shape has no style, safe to ignore */ |
289 |
+ } |
290 |
+ |
291 |
+ return inheritedStyles; |
292 |
+ } |
293 |
+ |
294 |
//---------------------------------------------------------------------------- |
295 |
+ void PassDownStyleProps(const XCAFPrs_Style& parent, XCAFPrs_Style& child) |
296 |
+ { |
297 |
+ if (!child.IsSetColorCurv() && parent.IsSetColorCurv()) |
298 |
+ { |
299 |
+ child.SetColorCurv(parent.GetColorCurv()); |
300 |
+ } |
301 |
+ |
302 |
+ if (!child.IsSetColorSurf() && parent.IsSetColorSurf()) |
303 |
+ { |
304 |
+ child.SetColorSurf(parent.GetColorSurfRGBA()); |
305 |
+ } |
306 |
+ |
307 |
+ if (child.Material().IsNull() && !parent.Material().IsNull()) |
308 |
+ { |
309 |
+ child.SetMaterial(parent.Material()); |
310 |
+ } |
311 |
+ }; |
312 |
+ |
313 |
+ //---------------------------------------------------------------------------- |
314 |
void AddLabel(const TDF_Label& label, vtkMatrix4x4* position, vtkMultiBlockDataSet* mb) |
315 |
{ |
316 |
if (this->ShapeTool->IsSimpleShape(label) && this->ShapeTool->IsTopLevel(label)) |
317 |
@@ -365,7 +488,11 @@ class vtkF3DOCCTReader::vtkInternals |
318 |
int GetHash(const TDF_Label& label) |
319 |
{ |
320 |
TopoDS_Shape aShape; |
321 |
+#if OCC_VERSION_HEX < 0x070800 |
322 |
return this->ShapeTool->GetShape(label, aShape) ? aShape.HashCode(INT_MAX) : 0; |
323 |
+#else |
324 |
+ return this->ShapeTool->GetShape(label, aShape) ? std::hash<TopoDS_Shape>{}(aShape) : 0; |
325 |
+#endif |
326 |
} |
327 |
|
328 |
//---------------------------------------------------------------------------- |
329 |
@@ -401,7 +528,6 @@ class vtkF3DOCCTReader::vtkInternals |
330 |
|
331 |
std::unordered_map<int, vtkSmartPointer<vtkPolyData> > ShapeMap; |
332 |
Handle(XCAFDoc_ShapeTool) ShapeTool; |
333 |
- Handle(XCAFDoc_ColorTool) ColorTool; |
334 |
#endif |
335 |
|
336 |
vtkF3DOCCTReader* Parent; |
337 |
@@ -424,7 +550,10 @@ class ProgressIndicator : public Message_ProgressIndic |
338 |
class ProgressIndicator : public Message_ProgressIndicator |
339 |
{ |
340 |
public: |
341 |
- explicit ProgressIndicator(vtkF3DOCCTReader* reader) { this->Reader = reader; } |
342 |
+ explicit ProgressIndicator(vtkF3DOCCTReader* reader) |
343 |
+ { |
344 |
+ this->Reader = reader; |
345 |
+ } |
346 |
|
347 |
protected: |
348 |
void Show(const Message_ProgressScope&, const Standard_Boolean) override |
349 |
@@ -493,7 +622,12 @@ int vtkF3DOCCTReader::RequestData( |
350 |
if (success) |
351 |
{ |
352 |
output->SetNumberOfBlocks(1); |
353 |
+#if F3D_PLUGIN_OCCT_XCAF |
354 |
+ const vtkSmartPointer<vtkPolyData> polydata = |
355 |
+ this->Internals->CreateShape(shape, TDF_Label()); |
356 |
+#else |
357 |
const vtkSmartPointer<vtkPolyData> polydata = this->Internals->CreateShape(shape); |
358 |
+#endif |
359 |
if (polydata && polydata->GetNumberOfCells() > 0) |
360 |
{ |
361 |
output->SetBlock(1, polydata); |
362 |
@@ -522,7 +656,6 @@ int vtkF3DOCCTReader::RequestData( |
363 |
} |
364 |
|
365 |
this->Internals->ShapeTool = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); |
366 |
- this->Internals->ColorTool = XCAFDoc_DocumentTool::ColorTool(doc->Main()); |
367 |
|
368 |
TDF_LabelSequence topLevelShapes; |
369 |
|
370 |
@@ -537,9 +670,9 @@ int vtkF3DOCCTReader::RequestData( |
371 |
this->Internals->ShapeTool->GetShape(label, shape); |
372 |
|
373 |
this->Internals->ShapeMap[this->Internals->GetHash(label)] = |
374 |
- this->Internals->CreateShape(shape); |
375 |
+ this->Internals->CreateShape(shape, label); |
376 |
|
377 |
- double progress = 0.5 + static_cast<double>(iLabel) / topLevelShapes.Length(); |
378 |
+ double progress = 0.5 + (static_cast<double>(iLabel) / topLevelShapes.Length()) / 2; |
379 |
this->InvokeEvent(vtkCommand::ProgressEvent, &progress); |
380 |
} |
381 |
|