b311480e |
1 | // Created on: 1999-09-27 |
2 | // Created by: Sergey ZARITCHNY |
3 | // Copyright (c) 1999-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include <QANewBRepNaming_BooleanOperationFeat.ixx> |
18 | #include <Standard_NullObject.hxx> |
19 | #include <Precision.hxx> |
20 | #include <TColgp_Array1OfPnt.hxx> |
21 | #include <TColStd_Array1OfInteger.hxx> |
22 | #include <TopTools_Array1OfShape.hxx> |
23 | #include <TColgp_Array1OfDir.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <BRepGProp.hxx> |
26 | #include <GProp_GProps.hxx> |
27 | #include <BRepAdaptor_Surface.hxx> |
28 | #include <BRep_Tool.hxx> |
29 | #include <Adaptor3d_HCurve.hxx> |
30 | #include <gp_Cylinder.hxx> |
31 | #include <gp_Cone.hxx> |
32 | #include <GeomAbs_SurfaceType.hxx> |
33 | #include <Geom_Ellipse.hxx> |
34 | #include <TopExp_Explorer.hxx> |
35 | #include <TopoDS_Iterator.hxx> |
36 | #include <TopoDS_Vertex.hxx> |
37 | #include <TopoDS_Edge.hxx> |
38 | #include <TopoDS.hxx> |
39 | #include <TopExp.hxx> |
40 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
41 | #include <TopTools_IndexedMapOfShape.hxx> |
42 | #include <TopTools_MapOfShape.hxx> |
7fd59977 |
43 | #include <TDF_Label.hxx> |
44 | #include <TDF_TagSource.hxx> |
45 | #include <TDataStd_Integer.hxx> |
46 | #include <TDataStd_Real.hxx> |
47 | #include <TDataStd_IntegerArray.hxx> |
48 | #include <TDataStd_Name.hxx> |
49 | #include <TNaming_Builder.hxx> |
50 | #include <TNaming_NamedShape.hxx> |
51 | #include <gp.hxx> |
52 | |
53 | #include <QANewBRepNaming_Loader.hxx> |
54 | |
0797d9d3 |
55 | #ifdef OCCT_DEBUG |
7fd59977 |
56 | #include <TDataStd_Name.hxx> |
57 | #endif |
58 | |
0797d9d3 |
59 | #ifdef OCCT_DEBUG |
7fd59977 |
60 | #include <TCollection_AsciiString.hxx> |
61 | #include <TDF_Tool.hxx> |
62 | #include <BRepTools.hxx> |
63 | #include <TNaming_Tool.hxx> |
64 | static void ModDbgTools_Write(const TopoDS_Shape& shape, |
65 | const Standard_CString filename) |
66 | { |
67 | ofstream save; |
68 | save.open(filename); |
69 | save << "DBRep_DrawableShape" << endl << endl; |
70 | if(!shape.IsNull()) BRepTools::Write(shape, save); |
71 | save.close(); |
72 | } |
73 | |
7fd59977 |
74 | #endif |
75 | |
76 | //======================================================================= |
77 | //function : QANewBRepNaming_BooleanOperationFeat |
78 | //purpose : |
79 | //======================================================================= |
80 | |
81 | QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat() {} |
82 | |
83 | //======================================================================= |
84 | //function : QANewBRepNaming_BooleanOperationFeat |
85 | //purpose : |
86 | //======================================================================= |
87 | |
88 | QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat(const TDF_Label& ResultLabel):QANewBRepNaming_TopNaming(ResultLabel) {} |
89 | |
90 | //======================================================================= |
91 | //function : Init |
92 | //purpose : |
93 | //======================================================================= |
94 | |
95 | void QANewBRepNaming_BooleanOperationFeat::Init(const TDF_Label& ResultLabel) { |
96 | if(ResultLabel.IsNull()) |
97 | Standard_NullObject::Raise("QANewBRepNaming_BooleanOperationFeat::Init The Result label is Null ..."); |
98 | myResultLabel = ResultLabel; |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : ModifiedFaces |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedFaces() const { |
0797d9d3 |
107 | #ifdef OCCT_DEBUG |
7fd59977 |
108 | const TDF_Label& ModifiedFacesLabel = ResultLabel().NewChild(); |
109 | TDataStd_Name::Set(ModifiedFacesLabel, "ModifiedFaces"); |
110 | return ModifiedFacesLabel; |
d3f26155 |
111 | #else |
7fd59977 |
112 | return ResultLabel().NewChild(); |
d3f26155 |
113 | #endif |
7fd59977 |
114 | } |
115 | |
116 | //======================================================================= |
117 | //function : ModifiedEdges |
118 | //purpose : |
119 | //======================================================================= |
120 | |
121 | TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedEdges() const { |
0797d9d3 |
122 | #ifdef OCCT_DEBUG |
7fd59977 |
123 | const TDF_Label& ModifiedEdgesLabel = ResultLabel().NewChild(); |
124 | TDataStd_Name::Set(ModifiedEdgesLabel, "ModifiedEdges"); |
125 | return ModifiedEdgesLabel; |
d3f26155 |
126 | #else |
7fd59977 |
127 | return ResultLabel().NewChild(); |
d3f26155 |
128 | #endif |
7fd59977 |
129 | } |
130 | |
131 | //======================================================================= |
132 | //function : DeletedFaces |
133 | //purpose : |
134 | //======================================================================= |
135 | |
136 | TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedFaces() const { |
0797d9d3 |
137 | #ifdef OCCT_DEBUG |
7fd59977 |
138 | const TDF_Label& DeletedFacesLabel = ResultLabel().NewChild(); |
139 | TDataStd_Name::Set(DeletedFacesLabel, "DeletedFaces"); |
140 | return DeletedFacesLabel; |
d3f26155 |
141 | #else |
7fd59977 |
142 | return ResultLabel().NewChild(); |
d3f26155 |
143 | #endif |
7fd59977 |
144 | } |
145 | |
146 | //======================================================================= |
147 | //function : DeletedEdges |
148 | //purpose : |
149 | //======================================================================= |
150 | |
151 | TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedEdges() const { |
0797d9d3 |
152 | #ifdef OCCT_DEBUG |
7fd59977 |
153 | const TDF_Label& DeletedEdgesLabel = ResultLabel().NewChild(); |
154 | TDataStd_Name::Set(DeletedEdgesLabel, "DeletedEdges"); |
155 | return DeletedEdgesLabel; |
d3f26155 |
156 | #else |
7fd59977 |
157 | return ResultLabel().NewChild(); |
d3f26155 |
158 | #endif |
7fd59977 |
159 | } |
160 | |
161 | //======================================================================= |
162 | //function : DeletedVertices |
163 | //purpose : |
164 | //======================================================================= |
165 | |
166 | TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedVertices() const { |
0797d9d3 |
167 | #ifdef OCCT_DEBUG |
7fd59977 |
168 | const TDF_Label& DeletedVerticesLabel = ResultLabel().NewChild(); |
169 | TDataStd_Name::Set(DeletedVerticesLabel, "DeletedVertices"); |
170 | return DeletedVerticesLabel; |
d3f26155 |
171 | #else |
7fd59977 |
172 | return ResultLabel().NewChild(); |
d3f26155 |
173 | #endif |
7fd59977 |
174 | } |
175 | |
176 | //======================================================================= |
177 | //function : NewShapes |
178 | //purpose : |
179 | //======================================================================= |
180 | |
181 | TDF_Label QANewBRepNaming_BooleanOperationFeat::NewShapes() const { |
0797d9d3 |
182 | #ifdef OCCT_DEBUG |
7fd59977 |
183 | const TDF_Label& NewShapesLabel = ResultLabel().NewChild(); |
184 | TDataStd_Name::Set(NewShapesLabel, "NewShapes"); |
185 | return NewShapesLabel; |
d3f26155 |
186 | #else |
7fd59977 |
187 | return ResultLabel().NewChild(); |
d3f26155 |
188 | #endif |
7fd59977 |
189 | } |
190 | |
191 | //======================================================================= |
192 | //function : Content |
193 | //purpose : |
194 | //======================================================================= |
195 | |
196 | TDF_Label QANewBRepNaming_BooleanOperationFeat::Content() const { |
0797d9d3 |
197 | #ifdef OCCT_DEBUG |
7fd59977 |
198 | const TDF_Label& ContentLabel = ResultLabel().NewChild(); |
199 | TDataStd_Name::Set(ContentLabel, "Content"); |
200 | return ContentLabel; |
d3f26155 |
201 | #else |
7fd59977 |
202 | return ResultLabel().NewChild(); |
d3f26155 |
203 | #endif |
7fd59977 |
204 | } |
205 | |
206 | //======================================================================= |
207 | //function : DeletedDegeneratedEdges |
208 | //purpose : |
209 | //======================================================================= |
210 | |
211 | TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedDegeneratedEdges() const { |
0797d9d3 |
212 | #ifdef OCCT_DEBUG |
7fd59977 |
213 | const TDF_Label& DegeneratedLabel = ResultLabel().NewChild(); |
214 | TDataStd_Name::Set(DegeneratedLabel, "DeletedDegeneratedEdges"); |
215 | return DegeneratedLabel; |
d3f26155 |
216 | #else |
7fd59977 |
217 | return ResultLabel().NewChild(); |
d3f26155 |
218 | #endif |
7fd59977 |
219 | } |
220 | |
221 | //======================================================================= |
222 | //function : ShapeType |
223 | //purpose : |
224 | //======================================================================= |
225 | |
226 | TopAbs_ShapeEnum QANewBRepNaming_BooleanOperationFeat::ShapeType(const TopoDS_Shape& theShape) { |
227 | TopAbs_ShapeEnum TypeSh = theShape.ShapeType(); |
228 | if (TypeSh == TopAbs_COMPOUND || TypeSh == TopAbs_COMPSOLID) { |
229 | TopoDS_Iterator itr(theShape); |
230 | if (!itr.More()) return TypeSh; |
231 | TypeSh = ShapeType(itr.Value()); |
232 | if(TypeSh == TopAbs_COMPOUND) return TypeSh; |
233 | itr.Next(); |
234 | for(; itr.More(); itr.Next()) |
235 | if(ShapeType(itr.Value()) != TypeSh) return TopAbs_COMPOUND; |
236 | } |
237 | return TypeSh; |
238 | } |
239 | |
240 | //======================================================================= |
241 | //function : GetShape |
242 | //purpose : |
243 | //======================================================================= |
244 | |
245 | TopoDS_Shape QANewBRepNaming_BooleanOperationFeat::GetShape(const TopoDS_Shape& theShape) const { |
246 | if (theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID) { |
247 | TopoDS_Iterator itr(theShape); |
248 | if (itr.More()) return itr.Value(); |
249 | } |
250 | return theShape; |
251 | } |
252 | |
253 | //======================================================================= |
254 | //function : LoadWire |
255 | //purpose : |
256 | //======================================================================= |
257 | |
258 | void QANewBRepNaming_BooleanOperationFeat::LoadWire(BRepAlgoAPI_BooleanOperation& MS) const { |
259 | // Naming of modified edges: |
260 | TNaming_Builder ModBuilder(ModifiedEdges()); |
261 | QANewBRepNaming_Loader::LoadModifiedShapes (MS, MS.Shape1(), TopAbs_EDGE, ModBuilder); |
262 | |
263 | // load generated vertexes |
264 | if(MS.HasGenerated()) { |
265 | TNaming_Builder nBuilder (NewShapes()); |
266 | QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_EDGE, nBuilder); |
267 | QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder); |
268 | } |
269 | // Naming of deleted edges, dangle vertices |
270 | if(MS.HasDeleted()){ |
271 | TNaming_Builder DelEBuilder(DeletedEdges()); |
272 | QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder); |
273 | TNaming_Builder DelVBuilder(DeletedVertices()); |
274 | QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_VERTEX, DelEBuilder); |
275 | } |
276 | } |
277 | |
278 | //======================================================================= |
279 | //function : LoadShell |
280 | //purpose : |
281 | //======================================================================= |
282 | |
283 | void QANewBRepNaming_BooleanOperationFeat::LoadShell(BRepAlgoAPI_BooleanOperation& MS) const { |
284 | // Naming of modified faces and dangle edges |
285 | TNaming_Builder ModFBuilder(ModifiedFaces()); |
286 | QANewBRepNaming_Loader::LoadModifiedShapes(MS, MS.Shape1(), TopAbs_FACE, ModFBuilder); |
287 | TNaming_Builder ModEBuilder(ModifiedEdges()); |
288 | QANewBRepNaming_Loader::LoadModifiedShapes(MS, MS.Shape1(), TopAbs_EDGE, ModEBuilder); |
289 | |
290 | if(MS.HasGenerated()) { |
291 | TNaming_Builder nBuilder (NewShapes()); |
292 | // generated Edges |
293 | QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder); |
294 | QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_FACE, nBuilder); |
295 | } |
296 | // Naming of deleted faces edges: |
297 | if(MS.HasDeleted()){ |
298 | TNaming_Builder DelFBuilder(DeletedFaces()); |
299 | QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_FACE, DelFBuilder); |
300 | |
301 | TNaming_Builder DelEBuilder(DeletedEdges()); |
302 | QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder); |
303 | } |
304 | } |
305 | |
306 | //======================================================================= |
307 | //function : LoadContent |
308 | //purpose : |
309 | //======================================================================= |
310 | |
311 | void QANewBRepNaming_BooleanOperationFeat::LoadContent(BRepAlgoAPI_BooleanOperation& MS) const { |
312 | if (MS.Shape().ShapeType() == TopAbs_COMPSOLID || MS.Shape().ShapeType() == TopAbs_COMPOUND) { |
313 | TopoDS_Iterator itr(MS.Shape()); |
314 | Standard_Integer nbShapes = 0; |
315 | while (itr.More()) { |
316 | nbShapes++; |
317 | itr.Next(); |
318 | } |
319 | if (nbShapes > 1) { |
320 | for (itr.Initialize(MS.Shape()); itr.More(); itr.Next()) { |
321 | TNaming_Builder bContent(Content()); |
322 | bContent.Generated(itr.Value()); |
323 | } |
324 | } |
325 | } |
326 | } |
327 | |
328 | //======================================================================= |
329 | //function : LoadResult |
330 | //purpose : |
331 | //======================================================================= |
332 | |
333 | void QANewBRepNaming_BooleanOperationFeat::LoadResult(BRepAlgoAPI_BooleanOperation& MS) const { |
334 | Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel()); |
335 | if (Tagger.IsNull()) return; |
336 | Tagger->Set(0); |
337 | TNaming_Builder Builder (ResultLabel()); |
338 | TopoDS_Shape aResult = MS.Shape(); |
339 | if (aResult.ShapeType() == TopAbs_COMPOUND) { |
340 | Standard_Integer nbSubResults = 0; |
341 | TopoDS_Iterator itr(aResult); |
342 | for (; itr.More(); itr.Next()) nbSubResults++; |
343 | if (nbSubResults == 1) { |
344 | itr.Initialize(aResult); |
345 | if (itr.More()) aResult = itr.Value(); |
346 | } |
347 | } |
348 | if (MS.Shape1().IsNull()) Builder.Generated(aResult); |
349 | else Builder.Modify(MS.Shape1(), aResult); |
350 | } |
351 | |
352 | //======================================================================= |
353 | //function : LoadDegenerated |
354 | //purpose : |
355 | //======================================================================= |
356 | |
357 | void QANewBRepNaming_BooleanOperationFeat::LoadDegenerated(BRepAlgoAPI_BooleanOperation& MS) const { |
358 | TopTools_IndexedMapOfShape allEdges; |
359 | TopExp::MapShapes(MS.Shape1(), TopAbs_EDGE, allEdges); |
360 | Standard_Integer i = 1; |
361 | for (; i <= allEdges.Extent(); i++) { |
362 | if (BRep_Tool::Degenerated(TopoDS::Edge(allEdges.FindKey(i)))) { |
363 | if (MS.IsDeleted(allEdges.FindKey(i))) { |
364 | TNaming_Builder DegeneratedBuilder(DeletedDegeneratedEdges()); |
365 | DegeneratedBuilder.Generated(allEdges.FindKey(i)); |
0797d9d3 |
366 | #ifdef OCCT_DEBUG |
7fd59977 |
367 | TDataStd_Name::Set(DegeneratedBuilder.NamedShape()->Label(), "DeletedDegenerated"); |
368 | #endif |
369 | } |
370 | } |
371 | } |
372 | } |
373 | |
374 | //======================================================================= |
375 | //function : IsResultChanged |
376 | //purpose : |
377 | //======================================================================= |
378 | |
379 | Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsResultChanged(BRepAlgoAPI_BooleanOperation& MS) const { |
380 | TopoDS_Shape ResSh = MS.Shape(); |
381 | if (MS.Shape().ShapeType() == TopAbs_COMPOUND) { |
382 | Standard_Integer nbSubResults = 0; |
383 | TopoDS_Iterator itr(MS.Shape()); |
384 | for (; itr.More(); itr.Next()) nbSubResults++; |
385 | if (nbSubResults == 1) { |
386 | itr.Initialize(MS.Shape()); |
387 | if (itr.More()) ResSh = itr.Value(); |
388 | } |
389 | } |
390 | return MS.Shape1().IsSame(ResSh); |
391 | } |
392 | //======================================================================= |
393 | // Workaround for evolution 1:n |
394 | //======================================================================= |
395 | static Standard_Boolean IsValidSurfType(const TopoDS_Face& theFace) { |
396 | BRepAdaptor_Surface anAdapt(theFace); |
397 | Handle( Adaptor3d_HCurve ) aBasisCurve; |
398 | const GeomAbs_SurfaceType& aType = anAdapt.GetType(); |
399 | if(aType == GeomAbs_Cylinder || aType == GeomAbs_Cone) |
400 | return Standard_True; |
401 | else if(aType == GeomAbs_SurfaceOfRevolution){ |
402 | aBasisCurve = anAdapt.BasisCurve(); |
403 | if (aBasisCurve->GetType() == GeomAbs_Line) |
404 | return Standard_True; |
405 | } |
406 | else if(aType == GeomAbs_SurfaceOfExtrusion) { |
407 | aBasisCurve = anAdapt.BasisCurve(); |
408 | if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse) |
409 | return Standard_True; |
410 | } |
0797d9d3 |
411 | #ifdef OCCT_DEBUG |
7fd59977 |
412 | ModDbgTools_Write(theFace, "Surf"); |
413 | #endif |
414 | return Standard_False; |
415 | } |
416 | //======================================================================= |
417 | //function : IsWRCase |
418 | //purpose : |
419 | //======================================================================= |
420 | |
421 | Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsWRCase(const BRepAlgoAPI_BooleanOperation& MS) { |
422 | const TopoDS_Shape& ObjSh = MS.Shape1(); |
423 | const TopoDS_Shape& ToolSh = MS.Shape2(); |
424 | const TopAbs_ShapeEnum& Type1 = ShapeType(ObjSh); |
425 | if(Type1 == TopAbs_COMPOUND || Type1 > TopAbs_FACE) return Standard_False; |
426 | const TopAbs_ShapeEnum& Type2 = ShapeType(ToolSh); |
427 | if(Type2 == TopAbs_COMPOUND || Type2 > TopAbs_FACE) return Standard_False; |
428 | TopTools_ListOfShape aList; |
429 | |
430 | |
431 | if(Type1 != TopAbs_FACE) { |
432 | TopExp_Explorer anExp(ObjSh, TopAbs_FACE); |
433 | for(;anExp.More();anExp.Next()) { |
434 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) |
435 | aList.Append(anExp.Current()); |
436 | } |
437 | } else |
438 | if(IsValidSurfType(TopoDS::Face(ObjSh))) |
439 | aList.Append(ObjSh); |
440 | if(aList.Extent() == 1) { |
441 | if(Type2 != TopAbs_FACE) { |
442 | TopExp_Explorer anExp(ToolSh, TopAbs_FACE); |
443 | for(;anExp.More();anExp.Next()) { |
444 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) |
445 | aList.Append(anExp.Current()); |
446 | } |
447 | } else |
448 | if(IsValidSurfType(TopoDS::Face(ToolSh))) |
449 | aList.Append(ToolSh); |
450 | if(aList.Extent() == 2) return Standard_True; |
451 | } |
452 | return Standard_False; |
453 | } |
454 | |
455 | //======================================================================= |
456 | static gp_Ax1 ComputeAxis(const TopoDS_Shape& theShape) { |
457 | TopoDS_Face aFace; |
458 | TopExp_Explorer anExp(theShape, TopAbs_FACE); |
459 | for(;anExp.More();anExp.Next()) { |
460 | aFace = TopoDS::Face(anExp.Current()); |
461 | BRepAdaptor_Surface anAdapt(aFace); |
462 | Handle( Adaptor3d_HCurve ) aBasisCurve; |
463 | const GeomAbs_SurfaceType& aType = anAdapt.GetType(); |
464 | if(aType == GeomAbs_Cylinder) |
465 | return anAdapt.Cylinder().Axis(); |
466 | else if(aType == GeomAbs_Cone) |
467 | return anAdapt.Cone().Axis(); |
468 | else if(aType == GeomAbs_SurfaceOfRevolution) |
469 | return anAdapt.AxeOfRevolution(); |
470 | else if(aType == GeomAbs_SurfaceOfExtrusion) { |
471 | aBasisCurve = anAdapt.BasisCurve(); |
472 | if (aBasisCurve->GetType() == GeomAbs_Circle) |
473 | return aBasisCurve->Circle().Axis(); |
474 | else if(aBasisCurve->GetType() == GeomAbs_Ellipse) |
475 | return aBasisCurve->Ellipse().Axis(); |
476 | } |
477 | } |
478 | return gp::OX(); |
479 | } |
480 | //============================================================================== |
481 | // |
482 | //========================================================================== |
483 | static Standard_Integer Identify(const TopoDS_Face& theFace, const gp_Ax1& theAx) { |
484 | GProp_GProps aGProp; |
485 | BRepGProp::SurfaceProperties(theFace, aGProp); |
486 | gp_Pnt aPoint = aGProp.CentreOfMass(); |
487 | gp_Vec aV1(theAx.Direction()); |
488 | gp_Vec aV2(theAx.Location(), aPoint); |
0797d9d3 |
489 | #ifdef OCCT_DEBUG |
7fd59977 |
490 | gp_Vec v1 = aV1.Crossed(aV2); |
491 | cout <<" Z of V1 = " << v1.XYZ().Z() << endl; |
492 | #endif |
493 | if((aV1.Crossed(aV2)).XYZ().Z() >= 0) return 1; //right orientation |
494 | return (-1); //left orientation |
495 | } |
496 | |
497 | //======================================================================= |
498 | //function : LoadModified11 |
499 | //purpose : 1 : 1 |
500 | //======================================================================= |
501 | |
502 | void QANewBRepNaming_BooleanOperationFeat::LoadModified11 (BRepAlgoAPI_BooleanOperation& MS, |
503 | const TopoDS_Shape& ShapeIn, |
504 | const TopAbs_ShapeEnum KindOfShape) const |
505 | |
506 | { |
507 | TopTools_MapOfShape View; |
508 | Standard_Boolean found = Standard_False; |
509 | TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape); |
510 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
511 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
512 | if (!View.Add(Root)) continue; |
5549deff |
513 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
514 | if(Shapes.Extent() == 1) {found = Standard_True; break;} |
515 | } |
516 | |
517 | if(found) { |
518 | View.Clear(); |
519 | ShapeExplorer.Init (ShapeIn, KindOfShape); |
520 | TNaming_Builder Builder(ModifiedFaces()); |
521 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
522 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
523 | if (!View.Add(Root)) continue; |
5549deff |
524 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
525 | if(Shapes.Extent() > 1) continue; |
526 | TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes); |
527 | for (;ShapesIterator.More (); ShapesIterator.Next ()) { |
528 | const TopoDS_Shape& newShape = ShapesIterator.Value (); |
529 | if (!Root.IsSame (newShape)) { |
530 | //put shapes with evolution 1:1 (may be Compound) |
0797d9d3 |
531 | #ifdef OCCT_DEBUG |
7fd59977 |
532 | TCollection_AsciiString entry; |
533 | TDF_Tool::Entry(Builder.NamedShape()->Label(), entry); |
534 | cout << "Add shape to Compound at Label = "<< entry <<endl; |
535 | #endif |
536 | Builder.Modify (Root,newShape); |
537 | } |
538 | } |
539 | } |
540 | } |
541 | } |
542 | //====================================================================== |
543 | static gp_Pnt GetCenterPoint(const TopoDS_Shape& theEdge) |
544 | { |
545 | GProp_GProps aGProp; |
546 | BRepGProp::LinearProperties(theEdge, aGProp); |
547 | return aGProp.CentreOfMass(); |
548 | } |
549 | //=================================================================== |
550 | static void SortRootFaces(TopTools_ListOfShape& theList, const TopoDS_Shape& theShape) |
551 | { |
552 | TopTools_ListOfShape aList; |
553 | Standard_Integer aNum = theList.Extent(); |
554 | if(aNum <= 1) return; |
555 | gp_Ax1 anAx = ComputeAxis(theShape); |
556 | TopTools_Array1OfShape ArS(1, aNum); |
557 | TColgp_Array1OfPnt ArP(1, aNum); |
558 | TColStd_Array1OfInteger ArI(1, aNum); |
559 | TopTools_ListIteratorOfListOfShape It(theList); |
560 | Standard_Integer i; |
561 | for(i=1;It.More();It.Next(),i++) { |
562 | ArS.SetValue(i, It.Value ()); |
563 | ArI.SetValue(i,0); |
564 | ArP.SetValue(i, GetCenterPoint(It.Value())); |
565 | |
566 | } |
567 | gp_Pnt aPnt = anAx.Location(); |
568 | Standard_Integer I, j; |
569 | for(j=1;j <= aNum; j++) { |
570 | if(ArI.Value(j) == -1) continue; |
571 | Standard_Real aD1 = aPnt.Distance(ArP(j)); |
572 | I = 0; |
573 | for(i=1;i <= aNum; i++) { |
574 | if(i==j) continue; |
575 | if(ArI.Value(i) == -1) continue; |
576 | Standard_Real aD2 = aPnt.Distance(ArP(i)); |
577 | if(aD2 < aD1) { |
578 | I = i; |
579 | aD1 = aD2; |
580 | } |
581 | } |
582 | if (I == 0) continue; |
583 | ArI.SetValue(I, -1); |
584 | aList.Append(ArS.Value(I)); |
585 | if(aList.Extent() == aNum -1) { |
586 | for(i=1; i<=aNum;i++) |
587 | if(ArI.Value(i) != -1) aList.Append(ArS.Value(i)); |
588 | } |
589 | } |
590 | theList.Assign(aList); |
591 | } |
592 | //======================================================================= |
593 | static void Sort2Faces(const TopTools_ListOfShape& Shapes, |
594 | const gp_Ax1& theAx, TopTools_ListOfShape& theList) |
595 | { |
596 | |
597 | TopTools_ListIteratorOfListOfShape It(Shapes); |
598 | for(;It.More();It.Next()) { |
599 | if(Identify(TopoDS::Face(It.Value()), theAx) == 1) |
600 | theList.Prepend(It.Value()); //Pos |
601 | else theList.Append(It.Value()); //Neg |
602 | } |
603 | } |
604 | |
605 | //======================================================================= |
606 | static void Sort3Faces(const TopTools_ListOfShape& theListIn, TopTools_ListOfShape& theListOut) |
607 | { |
608 | TopTools_ListIteratorOfListOfShape It (theListIn); |
609 | TopTools_Array1OfShape ArS(1, theListIn.Extent()); |
610 | TColgp_Array1OfPnt ArP(1, theListIn.Extent()); |
611 | |
612 | Standard_Integer i; |
613 | for(i=1;It.More();It.Next(),i++) { |
614 | ArS.SetValue(i, It.Value()); |
615 | ArP.SetValue(i, GetCenterPoint(It.Value())); |
616 | } |
617 | |
618 | Standard_Boolean found = Standard_False; |
1d47d8d0 |
619 | Standard_Integer j, i1 = 0, i2 = 0, i3 = 0; |
7fd59977 |
620 | TopoDS_Edge anEdge; |
621 | for(i=1;i<=3;i++) { |
622 | TopExp_Explorer anExp1(ArS.Value(i), TopAbs_EDGE); |
623 | for(;anExp1.More();anExp1.Next()) { |
624 | for(j=1;j<=3;j++) { |
625 | if(i==j) continue; |
626 | TopExp_Explorer anExp2(ArS.Value(j), TopAbs_EDGE); |
627 | for(;anExp2.More();anExp2.Next()) { |
628 | if(anExp1.Current().IsSame(anExp2.Current())){ |
629 | found = Standard_True; |
630 | anEdge = TopoDS::Edge(anExp1.Current()); |
631 | break; |
632 | } |
633 | } |
634 | if(found) break; |
635 | } |
636 | if(found) { |
637 | switch(i+j) { |
638 | case 3: //12 |
639 | i1=1;i2=2; i3=3; |
640 | break; |
641 | case 4: //13 |
642 | i1=1;i2=3; i3=2; |
643 | break; |
644 | case 5: //23 |
645 | i1=2;i2=3; i3=1; |
646 | } |
647 | break; |
648 | } |
649 | } |
650 | if(found) break; |
651 | } |
652 | |
653 | //i1,i2 - two adjacent faces via sim-edge |
654 | gp_Pnt aPnt1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); |
655 | gp_Pnt aPnt2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge)); |
656 | gp_Vec aVec(aPnt1, aPnt2); |
657 | gp_Ax1 anAx(aPnt1, gp_Dir(aVec)); |
658 | if (Identify(TopoDS::Face(ArS.Value(i1)), anAx) == -1) {//neg |
659 | i=i2; i2=i1; //i1 < = > i2 |
660 | i1=i; |
661 | } |
662 | theListOut.Append(ArS.Value(i1)); |
663 | theListOut.Append(ArS.Value(i2)); |
664 | theListOut.Append(ArS.Value(i3)); //single |
665 | } |
666 | //======================================================================= |
667 | //function : Load1nFaces |
668 | //purpose : |
669 | //======================================================================= |
670 | |
671 | void QANewBRepNaming_BooleanOperationFeat::Load1nFaces(BRepAlgoAPI_BooleanOperation& MS, const TopoDS_Shape& ShapeIn) const |
672 | { |
673 | |
674 | TopTools_MapOfShape View; |
675 | TopTools_ListOfShape aListR; |
676 | TopExp_Explorer ShapeExplorer (ShapeIn, TopAbs_FACE); |
677 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
678 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
679 | if (!View.Add(Root)) continue; |
5549deff |
680 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
681 | if(Shapes.Extent() < 2) continue; |
682 | aListR.Append(Root); |
683 | } |
684 | if(ShapeIn.IsEqual(MS.Shape1())) |
685 | if(aListR.Extent() > 1) SortRootFaces(aListR, ShapeIn); |
686 | |
687 | TopTools_ListIteratorOfListOfShape Itr(aListR); |
688 | for(;Itr.More();Itr.Next()) { |
689 | const TopoDS_Shape& Root = Itr.Value(); |
5549deff |
690 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
691 | TopTools_ListOfShape aList; |
692 | gp_Ax1 anAx = ComputeAxis(MS.Shape2()); |
693 | if(Shapes.Extent() == 2) |
694 | Sort2Faces(Shapes, anAx, aList); |
695 | else if(Shapes.Extent() == 3) |
696 | Sort3Faces(Shapes, aList); |
697 | TopTools_ListIteratorOfListOfShape It(aList); |
698 | for(;It.More();It.Next()) { |
699 | TNaming_Builder aBuilder(NewShapes()); |
700 | // aBuilder.Modify(Root,It.Value ()); |
701 | aBuilder.Generated(It.Value ()); |
702 | } |
703 | } |
704 | } |
705 | |
706 | //======================================================================= |
707 | //function : LoadModified faces |
708 | //purpose : 1 : n modification |
709 | //======================================================================= |
710 | |
711 | void QANewBRepNaming_BooleanOperationFeat::LoadModified1n (BRepAlgoAPI_BooleanOperation& MS, |
712 | const TopoDS_Shape& ShapeIn, |
713 | const TopAbs_ShapeEnum KindOfShape) const |
714 | |
715 | { |
716 | //fill modification 1:n |
717 | TopTools_MapOfShape View; |
718 | Standard_Integer aNum = 0; |
719 | TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape); |
720 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
721 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
722 | if (!View.Add(Root)) continue; |
5549deff |
723 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
724 | if(Shapes.Extent() >= 2) aNum += Shapes.Extent(); |
725 | } |
726 | |
727 | View.Clear(); |
728 | const TopoDS_Shape& Tool = MS.Shape2(); |
729 | ShapeExplorer.Init (Tool, KindOfShape); |
730 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
731 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
732 | if (!View.Add(Root)) continue; |
5549deff |
733 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
7fd59977 |
734 | if(Shapes.Extent() >= 2) aNum += Shapes.Extent(); |
735 | } |
736 | |
737 | Handle(TDataStd_IntegerArray) aSAR; |
738 | if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) { |
739 | //not find |
740 | aSAR = TDataStd_IntegerArray::Set(ResultLabel(), 1, 2); |
741 | aSAR->SetValue(1, 0); //tag num for faces structure |
742 | aSAR->SetValue(2, 0); //tag num for edges structure |
743 | } |
744 | |
745 | if(aSAR->Value(2)) { |
746 | Standard_Integer aNE =0; |
747 | TDF_Label aLab = ResultLabel().FindChild(aSAR->Value(2)); |
748 | Handle(TDataStd_Integer) anAtt; |
749 | if(aLab.FindAttribute(TDataStd_Integer::GetID(), anAtt) ) |
750 | aNE = anAtt->Get(); |
751 | TDF_Label aFLab = ResultLabel().FindChild(aLab.Tag() + aNE); |
752 | if(!aFLab.FindAttribute(TDataStd_Integer::GetID(), anAtt)) |
753 | aSAR->SetValue(1, 0); |
754 | } |
755 | TDF_Label aLabelFDS; |
756 | if(aSAR->Value(1)) |
757 | aLabelFDS = ResultLabel().FindChild(aSAR->Value(1)); // !=0 -already exist |
758 | else { |
759 | // initial creation of FDS structure |
760 | Handle(TDF_TagSource) aTS; |
761 | ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS); |
762 | aLabelFDS = NewShapes(); |
763 | // aLabelFDS = ResultLabel().FindChild(aSAR->Value(1)); |
764 | aSAR->SetValue(1, aLabelFDS.Tag()); //keep tag |
765 | aTS->Set(aLabelFDS.Tag()-1); |
766 | } |
767 | Handle(TDataStd_Integer) anAtt; |
768 | if(aLabelFDS.FindAttribute(TDataStd_Integer::GetID(), anAtt) ) { |
769 | // modification : check compatibility |
770 | if(anAtt->Get() != aNum) { |
771 | cout << "WARNING: Case isn't mantained - Number of Faces was changed!"<<endl; |
772 | // mark all structure as Deleted |
773 | Standard_Integer aN = aLabelFDS.Tag()+anAtt->Get(); |
774 | for(Standard_Integer i=aLabelFDS.Tag(); i < aN; i++) { |
775 | TDF_Label aLab = ResultLabel().FindChild(i, Standard_False); |
776 | if(!aLab.IsNull()) { |
777 | Handle(TNaming_NamedShape) aNS; |
778 | if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { |
779 | TopoDS_Shape aShape = aNS->Get(); |
780 | TNaming_Builder aBuilder(aLab); |
781 | aBuilder.Delete(aShape); //Deleted |
782 | } |
783 | } |
784 | } |
785 | // |
786 | Handle(TDF_TagSource) aTS; |
787 | ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS); |
788 | if(!aTS.IsNull()) |
789 | aTS->Set(aLabelFDS.Tag()); |
790 | anAtt->Set(aNum); |
791 | } |
792 | } else |
793 | TDataStd_Integer::Set(aLabelFDS, aNum); //keep number of faces |
794 | |
795 | Load1nFaces(MS, ShapeIn); |
796 | Load1nFaces(MS, Tool); |
797 | } |
798 | |
799 | |
800 | //====================================================================== |
801 | static Standard_Boolean IsDirectionPositive (const gp_Ax1& theAx, const gp_Pnt thePnt1, |
802 | const gp_Pnt thePnt2) { |
803 | Standard_Boolean isPositive; |
804 | gp_Vec aVec1(theAx.Direction()); |
805 | gp_Vec aVec2(thePnt1, thePnt2); |
0797d9d3 |
806 | #ifdef OCCT_DEBUG |
7fd59977 |
807 | // gp_Vec v1 = aVec1.Crossed(aVec2); |
808 | // cout <<" Z of V1 = " << v1.XYZ().Z() << endl; |
809 | #endif |
810 | if((aVec1.Crossed(aVec2)).XYZ().Z() >= 0) isPositive = Standard_True; |
811 | else |
812 | isPositive = Standard_False; |
813 | return isPositive; |
814 | } |
815 | //====================================================================== |
816 | // i => ArS[i] : ArP[i] ; i = ArI[j] |
817 | //====================================================================== |
818 | static void SortEdges2(const TColgp_Array1OfPnt& theArP, const gp_Ax1& theAx, |
819 | TColStd_Array1OfInteger& theArI) |
820 | { |
821 | gp_Pnt aPnt = theAx.Location(); |
822 | //sort : the nearest point must be first |
823 | Standard_Real aD1 = aPnt.Distance(theArP.Value(1)); |
824 | Standard_Real aD2 = aPnt.Distance(theArP.Value(2)); |
825 | if(aD1 < aD2) { |
826 | theArI.SetValue(1, 1); |
827 | theArI.SetValue(2, 2); |
828 | } else { |
829 | theArI.SetValue(1, 2); //change order |
830 | theArI.SetValue(2, 1); |
831 | } |
832 | } |
833 | //====================================================================== |
834 | // i => ArS[i] : ArP[i] ; i = ArI[j] |
835 | //====================================================================== |
836 | static void SortEdges3(const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP, |
837 | const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI) |
838 | { |
1d47d8d0 |
839 | Standard_Integer i, j, i1 = 0,i2 = 0, i3 = 0; |
7fd59977 |
840 | TopoDS_Shape aV; |
841 | Standard_Boolean adjacent = Standard_False; |
842 | for(i=1;i<=3;i++) { |
843 | for(j=1;j<=3;j++) { |
844 | if(i==j) continue; |
845 | const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i))); |
846 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j))); |
847 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j))); |
848 | if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) {adjacent = Standard_True;aV = aV11;} |
849 | else { |
850 | const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i))); |
851 | if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {adjacent = Standard_True;aV = aV12;} |
852 | } |
853 | if(adjacent) { |
854 | Standard_Integer aSum = i+j; |
855 | switch(aSum) { |
856 | case 3: //12 |
857 | i1 = 3;i2 = 1;i3 = 2; |
858 | break; |
859 | case 4: //13 |
860 | i1 = 2; i2 = 1;i3 = 3; |
861 | break; |
862 | case 5: //23 |
863 | i1 = 1; i2 = 2;i3 = 3; |
864 | } |
865 | break; |
866 | } |
867 | } |
868 | if(adjacent) break; |
869 | } |
870 | gp_Pnt aPnt = theAx.Location(); |
871 | // i1 - index of single edge |
872 | Standard_Real aD1 = aPnt.Distance(theArP.Value(i1)); |
873 | Standard_Real aD2 = aPnt.Distance(theArP.Value(i2)); |
874 | if(aD1 > aD2) { //cyclic shift |
875 | Standard_Integer aN = i3;// i1 => i3 - to the end |
876 | i3 = i1; i1 = aN; |
877 | // pair of adjacent i1, i2 |
878 | gp_Pnt aCP = BRep_Tool::Pnt(TopoDS::Vertex(aV)); |
879 | if(!IsDirectionPositive(theAx, aCP, theArP.Value(i1))) {//first must be positive direction |
880 | // change i1 <=>i2 |
881 | aN = i2; i2 = i1; |
882 | i1 = aN; |
883 | } |
884 | } else { |
885 | // pair of adjacent i2, i3 |
886 | gp_Pnt aCP = BRep_Tool::Pnt(TopoDS::Vertex(aV)); |
887 | if(!IsDirectionPositive(theAx, aCP, theArP.Value(i2))) {//first must be positive direction |
888 | // change i2 <=>i3 |
889 | Standard_Integer aN = i3; i3 = i2; |
890 | i2 = aN; |
891 | } |
892 | } |
893 | // order i1, i2, i3 |
894 | theArI.SetValue(1, i1); |
895 | theArI.SetValue(2, i2); |
896 | theArI.SetValue(3, i3); |
897 | } |
898 | |
899 | //====================================================================== |
900 | // i => ArS[i] : ArP[i] ; i = ArI[j] |
901 | //====================================================================== |
902 | static void SortEdges4(const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP, |
903 | const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI) |
904 | { |
905 | // 1. find adjacent edges, build pairs in ArI |
906 | // 2. find nearest pair, reorganize ArI |
907 | // 3. sort inside pairs |
908 | // ======================================= |
1d47d8d0 |
909 | Standard_Integer i, j, i1 = 0,i2 = 0, i3 = 0, i4 = 0; |
7fd59977 |
910 | // 1. |
911 | TopoDS_Shape aV1; |
912 | for(i=1;i<=4;i++) { |
913 | const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i))); |
914 | const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i))); |
1d47d8d0 |
915 | Standard_Boolean aDjacent = Standard_False; |
7fd59977 |
916 | for(j=1;j<=4;j++) { |
917 | if(i==j) continue; |
918 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j))); |
919 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j))); |
920 | aDjacent = Standard_False; |
921 | if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV11;} |
922 | else |
923 | if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV12;} |
924 | if(aDjacent) { |
925 | aDjacent = Standard_True; |
926 | Standard_Integer aSum = i+j; |
927 | i1 = i; i2 = j; |
928 | switch(aSum) { |
929 | case 3: //12 |
930 | i3 = 3; i4 = 4; |
931 | break; |
932 | case 4: //13 |
933 | i3 = 2; i4 = 4; |
934 | break; |
935 | case 5: //14 |
936 | i3 = 2; i4 = 3; |
937 | break; |
938 | } |
939 | break; |
940 | } |
941 | } |
942 | if(aDjacent) break; |
943 | } |
944 | // i1,i2 - first pair of adjacent: aV1. |
945 | // i3,i4 - next pair of adjacent: aV2. |
946 | // find agjacent V (i3-i4) |
947 | TopoDS_Shape aV2; |
948 | const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i3))); |
949 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i4))); |
950 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4))); |
951 | if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) aV2 = aV11; |
952 | else { |
953 | const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i3))); |
954 | if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV2 = aV12; |
955 | } |
956 | |
957 | // 2. find nearest pair |
958 | gp_Pnt aCP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1)); |
959 | gp_Pnt aCP2 = BRep_Tool::Pnt(TopoDS::Vertex(aV2)); |
960 | gp_Pnt aPnt = theAx.Location(); |
961 | Standard_Real aD1 = aPnt.Distance(aCP1);//i1-i2 |
962 | Standard_Real aD2 = aPnt.Distance(aCP2);//i3-i4 |
963 | if(aD1 > aD2) { //change order of pairs |
964 | Standard_Integer a3 = i3;// i1,i2 => i3,i4 - to the end |
965 | Standard_Integer a4 = i4; |
966 | i3 = i1; i4 = i2; |
967 | i1 = a3; i2 = a4; |
968 | gp_Pnt aP = aCP2; |
969 | aCP2 = aCP1; |
970 | aCP1 = aP; |
971 | // pair of adjacent i1-i2 is the nearest |
972 | } |
973 | |
974 | // 3. sort inside pairs |
975 | if(!IsDirectionPositive(theAx, aCP1, theArP.Value(i1))) {//first must be positive direction |
976 | // change i1 <=> i2 |
977 | Standard_Integer aN = i2; i2 = i1; |
978 | i1 = aN; |
979 | } |
980 | |
981 | if(!IsDirectionPositive(theAx, aCP2, theArP.Value(i3))) {//first must be positive direction |
982 | // change i3 <=> i4 |
0797d9d3 |
983 | #ifdef OCCT_DEBUG |
7fd59977 |
984 | cout << "SortEdges4: i3 = "<<i3<< "i4 = "<< i4 << endl; |
985 | #endif |
986 | Standard_Integer aN = i4; i4 = i3; |
987 | i3 = aN; |
988 | } |
989 | |
990 | // 4. final order i1, i2, i3, i4 - Ok |
0797d9d3 |
991 | #ifdef OCCT_DEBUG |
7fd59977 |
992 | cout << "SortEdges4: i1 = " <<i1<<" i2 = "<<i2<< " i3 = "<<i3<< "i4 = "<< i4 << endl; |
993 | #endif |
994 | theArI.SetValue(1, i1); |
995 | theArI.SetValue(2, i2); |
996 | theArI.SetValue(3, i3); |
997 | theArI.SetValue(4, i4); |
998 | } |
999 | // ====================================================================== |
1000 | static void SortEdges5 (const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP, |
1001 | const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI) |
1002 | { |
1003 | // ======================================= |
1004 | // 1. find middle edge from gr. of 3 edges, build two groups in ArI |
1005 | // 2. find nearest group, reorganize ArI - nerest => top |
1006 | // 3. sort inside groups |
1007 | // 3.1. sort inside group of 2 edges |
1008 | // 3.2. sort inside group of 3 edges |
1009 | // ======================================= |
1010 | Standard_Integer i, j, i1,i2, i3, i4, i5; |
1011 | // 1. |
1012 | TopoDS_Shape aV1, aV2, aV; |
1013 | Standard_Integer I=0, J1=0, J2=0; |
1014 | for(i=1;i<=5;i++) { |
1015 | Standard_Boolean found = Standard_False; |
1016 | const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i))); |
1017 | for(j=1;j<=5;j++) { |
1018 | if(i==j) continue; |
1019 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j))); |
1020 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j))); |
1021 | if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) { |
1022 | aV1 = aV11; I = i; J1 = j; |
1023 | found = Standard_True; |
1024 | break; |
1025 | } |
1026 | } |
1027 | if (found) { |
1028 | found = Standard_False; |
1029 | const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i))); |
1030 | for(j=1;j<=5;j++) { |
1031 | if(i==j) continue; |
1032 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j))); |
1033 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j))); |
1034 | if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) { |
1035 | aV2 = aV12; J2 = j; |
0797d9d3 |
1036 | #ifdef OCCT_DEBUG |
7fd59977 |
1037 | if(I != i) cout << "WARNING:: I != i, I = " << I << ", i = " << i <<endl; |
1038 | #endif |
1039 | found = Standard_True; |
1040 | break; |
1041 | } |
1042 | } |
1043 | } |
1044 | if (found) break; |
1045 | } |
1046 | // aV1, aV2 - vetexes of middle Edge, I - index of middle Edge, J1, J2 = indexes of |
1047 | // adjacent edges of the middle edge |
1048 | |
1049 | // init & shift group from 3 edges on the top |
1050 | i1=J1; i2=I; i3 = J2; i4=0; i5=0; |
1051 | for(i=1; i<=5;i++) { |
1052 | if(i==i1 || i==i2 ||i==i3) continue; |
1053 | if(!i4) i4=i; |
1054 | else i5 = i; |
1055 | } |
1056 | |
1057 | // find agjacent V (i4-i5) |
1058 | TopoDS_Shape aV3; |
1059 | const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i4))); |
1060 | const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i5))); |
1061 | const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i5))); |
1062 | if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) aV3 = aV11; |
1063 | else { |
1064 | const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4))); |
1065 | if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV3 = aV12; |
1066 | } |
1067 | |
1068 | // 2. find nearest group (aV1, aV3), reorganize ArI - nerest => top |
1069 | gp_Pnt aDP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1)); |
7fd59977 |
1070 | gp_Pnt aDP3 = BRep_Tool::Pnt(TopoDS::Vertex(aV3)); |
1071 | gp_Pnt aPnt = theAx.Location(); |
1072 | Standard_Real aD1 = aPnt.Distance(aDP1);//i1-i2-i3 |
1073 | Standard_Real aD2 = aPnt.Distance(aDP3);//i4-i5 |
1074 | Standard_Integer aTop = 3; |
1075 | if(aD1 > aD2) { //change order of groups |
1076 | aTop = 2; |
1077 | Standard_Integer a4 = i4;// i1,i2 => i4,i5 - to the end |
1078 | Standard_Integer a5 = i5; |
1079 | i4 = i2; i5 = i1; // i4 - middle edge |
1080 | i1 = a4; i2 = a5; |
1081 | gp_Pnt aP1 = aDP1; |
1082 | aDP1 = aDP3; |
1083 | aDP3 = aP1; |
1084 | // goup of 2 edges i1-i2 is the nearest |
1085 | } |
1086 | // 3.1. sort inside group of 2 edges |
1087 | gp_Pnt aDP, aCP; |
1088 | if(aTop == 2) {aDP = aDP1; aCP = theArP.Value(i1);} //i1,i2 |
1089 | else {aDP = aDP3; aCP = theArP.Value(i4);} //i4, i5 - group of 2 edges at the bottom |
1090 | if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction |
1091 | Standard_Integer aN; |
6d1a5d3a |
1092 | if(aTop == 2) { |
7fd59977 |
1093 | // change i1 <=> i2 |
1094 | aN = i2; i2 = i1; |
1095 | i1 = aN; |
1096 | } else { |
1097 | // change i4 <=> i5 |
1098 | aN = i5; i5 = i4; |
1099 | i4 = aN; |
1100 | } |
1101 | } |
1102 | // 3.2. sort inside group of 3 edges |
1103 | if(aTop == 2) { |
1104 | //i3,i4,i5 |
1105 | aDP = theArP.Value(i4); //center of middle edge |
1106 | aCP = theArP.Value(i3); |
1107 | } else { |
1108 | //i1,i2,i3 |
1109 | aDP = theArP.Value(i2); |
1110 | aCP = theArP.Value(i1); |
1111 | } |
1112 | |
1113 | if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction |
1114 | Standard_Integer aN; |
6d1a5d3a |
1115 | if(aTop == 2) { |
7fd59977 |
1116 | // change i3 <=> i5 |
1117 | aN = i5; i5 = i3; |
1118 | i3 = aN; |
1119 | } else { |
1120 | // change i1 <=> i3 |
1121 | aN = i3; i3 = i1; |
1122 | i1 = aN; |
1123 | } |
1124 | } |
1125 | // 4. final order i1, i2, i3, i4, i5 - Ok |
1126 | theArI.SetValue(1, i1); |
1127 | theArI.SetValue(2, i2); |
1128 | theArI.SetValue(3, i3); |
1129 | theArI.SetValue(4, i4); |
1130 | theArI.SetValue(5, i5); |
1131 | } |
1132 | //======================================================================= |
1133 | static void FindAdjacent2(const TopTools_ListOfShape& theList, |
1134 | TopTools_ListOfShape& theListOfEdges) { |
1135 | TopTools_ListIteratorOfListOfShape It (theList); |
1136 | const TopoDS_Shape& aShape1 = It.Value (); It.Next (); |
1137 | const TopoDS_Shape& aShape2 = It.Value (); |
1138 | if(!aShape1.IsNull() && !aShape2.IsNull()) { |
1139 | TopExp_Explorer anExp1(aShape1, TopAbs_EDGE); |
1140 | for(;anExp1.More();anExp1.Next()) { |
1141 | TopExp_Explorer anExp2(aShape2, TopAbs_EDGE); |
1142 | for(;anExp2.More();anExp2.Next()) { |
1143 | if(anExp1.Current().IsSame(anExp2.Current())) |
1144 | theListOfEdges.Append(anExp1.Current()); |
1145 | } |
1146 | } |
1147 | } |
1148 | } |
1149 | //======================================================================= |
1150 | static void FindAdjacent3(const TopTools_ListOfShape& theList, |
1151 | TopTools_ListOfShape& theListOfEdges) { |
1152 | TopTools_ListIteratorOfListOfShape It (theList); |
1153 | TopTools_Array1OfShape ArS(1, theList.Extent()); |
1154 | TColgp_Array1OfPnt ArP(1, theList.Extent()); |
1155 | TColgp_Array1OfDir ArD(1, theList.Extent()); |
1156 | Standard_Integer i; |
1157 | for(i=1;It.More();It.Next(),i++) { |
1158 | ArS.SetValue(i, It.Value()); |
1159 | gp_Ax1 anAx = ComputeAxis(It.Value()); |
1160 | ArP.SetValue(i, anAx.Location()); |
1161 | ArD.SetValue(i, anAx.Direction()); |
1162 | } |
1163 | Standard_Boolean aDjacent = Standard_False; |
1d47d8d0 |
1164 | Standard_Integer j, i2 = 0, i3 = 0; //i2, i3 - indexes of two adjacent faces having the same surface |
7fd59977 |
1165 | Standard_Integer i1 = 0; //single face |
1166 | for(i=1;i<=3;i++) { |
1167 | for(j=1;j<=3;j++) { |
1168 | if(i==j) continue; |
1169 | if(ArP.Value(i).IsEqual(ArP.Value(j), Precision::Confusion()) |
1170 | && ArD.Value(i).IsEqual(ArD.Value(j), Precision::Angular())) { |
1171 | aDjacent = Standard_True; |
1172 | Standard_Integer aSum = i+j; |
1173 | switch(aSum) { |
1174 | case 3: //12 |
1175 | i1 = 3; i2 = 1; i3 = 2; |
1176 | break; |
1177 | case 4: //13 |
1178 | i1 = 2; i2 = 1; i3 = 3; |
1179 | break; |
1180 | case 5: //23 |
1181 | i1 = 1; i2 = 2; i3 = 3; |
1182 | break; |
1183 | default: |
1184 | i1 = 1; i2 = 2; i3 = 3; |
1185 | } |
1186 | break; |
1187 | } |
1188 | } |
1189 | if(aDjacent) break; |
1190 | } |
1191 | |
1192 | TopExp_Explorer anExp1(ArS.Value(i1), TopAbs_EDGE); |
1193 | for(;anExp1.More();anExp1.Next()) { |
1194 | Standard_Boolean found = Standard_False; |
1195 | TopExp_Explorer anExp2(ArS.Value(i2), TopAbs_EDGE); |
1196 | for(;anExp2.More();anExp2.Next()) { |
1197 | if(anExp1.Current().IsSame(anExp2.Current())) |
1198 | {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;} |
1199 | } |
1200 | if(!found) { |
1201 | TopExp_Explorer anExp3(ArS.Value(i3), TopAbs_EDGE); |
1202 | for(;anExp3.More();anExp3.Next()) { |
1203 | if(anExp1.Current().IsSame(anExp3.Current())) |
1204 | {theListOfEdges.Append(anExp1.Current());break;} |
1205 | } |
1206 | } |
1207 | } |
1208 | } |
1209 | //======================================================================= |
1210 | static void FindAdjacent4(const TopTools_ListOfShape& theList, |
1211 | TopTools_ListOfShape& theListOfEdges) { |
1212 | TopTools_ListIteratorOfListOfShape It (theList); |
1213 | TopTools_Array1OfShape ArS(1, theList.Extent()); |
1214 | TColgp_Array1OfPnt ArP(1, theList.Extent()); |
1215 | TColgp_Array1OfDir ArD(1, theList.Extent()); |
1216 | Standard_Integer i; |
1217 | for(i=1;It.More();It.Next(),i++) { |
1218 | ArS.SetValue(i, It.Value()); |
1219 | gp_Ax1 anAx = ComputeAxis(It.Value()); |
1220 | ArP.SetValue(i, anAx.Location()); |
1221 | ArD.SetValue(i, anAx.Direction()); |
1222 | } |
1223 | //find pairs |
1224 | Standard_Integer j, i3=0, i4 = 0;//i3, i4 - indexes of two adjacent faces having the same surface |
1225 | Standard_Integer i1 = 0, i2 = 0; |
1226 | Standard_Boolean aDjacent = Standard_False; |
1227 | for(i=1;i<=4;i++) { |
1228 | for(j=1;j<=4;j++) { |
1229 | if(i==j) continue; |
1230 | if(ArP.Value(i).IsEqual(ArP.Value(j), Precision::Confusion()) |
1231 | && ArD.Value(i).IsEqual(ArD.Value(j), Precision::Angular())) { |
1232 | aDjacent = Standard_True; |
1233 | Standard_Integer aSum = i+j; |
1234 | i1 = i; i2 = j; |
1235 | switch(aSum) { |
1236 | case 3: //12 |
1237 | i3 = 3; i4 = 4; |
1238 | break; |
1239 | case 4: //13 |
1240 | i3 = 2; i4 = 4; |
1241 | break; |
1242 | case 5: //14 |
1243 | i3 = 2; i4 = 3; |
1244 | break; |
1245 | default: |
1246 | i3 = 3; i4 = 4; |
1247 | } |
1248 | break; |
1249 | } |
1250 | } |
1251 | if(aDjacent) break; |
1252 | } |
1253 | |
1254 | TopExp_Explorer anExp1(ArS.Value(i1), TopAbs_EDGE); |
1255 | for(;anExp1.More();anExp1.Next()) { |
1256 | Standard_Boolean found = Standard_False; |
1257 | TopExp_Explorer anExp2(ArS.Value(i3), TopAbs_EDGE); |
1258 | for(;anExp2.More();anExp2.Next()) { |
1259 | if(anExp1.Current().IsSame(anExp2.Current())) |
1260 | {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;} |
1261 | } |
1262 | if(!found) { |
1263 | TopExp_Explorer anExp3(ArS.Value(i4), TopAbs_EDGE); |
1264 | for(;anExp3.More();anExp3.Next()) { |
1265 | if(anExp1.Current().IsSame(anExp3.Current())) |
1266 | {theListOfEdges.Append(anExp1.Current());break;} |
1267 | } |
1268 | } |
1269 | } |
1270 | // |
1271 | anExp1.Init(ArS.Value(i2), TopAbs_EDGE); |
1272 | for(;anExp1.More();anExp1.Next()) { |
1273 | Standard_Boolean found = Standard_False; |
1274 | TopExp_Explorer anExp2(ArS.Value(i3), TopAbs_EDGE); |
1275 | for(;anExp2.More();anExp2.Next()) { |
1276 | if(anExp1.Current().IsSame(anExp2.Current())) |
1277 | {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;} |
1278 | } |
1279 | if(!found) { |
1280 | TopExp_Explorer anExp3(ArS.Value(i4), TopAbs_EDGE); |
1281 | for(;anExp3.More();anExp3.Next()) { |
1282 | if(anExp1.Current().IsSame(anExp3.Current())) |
1283 | {theListOfEdges.Append(anExp1.Current());break;} |
1284 | } |
1285 | } |
1286 | } |
1287 | } |
1288 | |
1289 | //======================================================================= |
1290 | // SortEdges: returns |
1291 | //======================================================================= |
1292 | static void SortEdges(const TopTools_ListOfShape& theListE, const gp_Ax1& theAx, |
1293 | TopTools_Array1OfShape& theARS) |
1294 | { |
1295 | |
1296 | Standard_Integer aNE1 = theListE.Extent(); |
1297 | TopTools_Array1OfShape ArS(1, aNE1); |
1298 | TColgp_Array1OfPnt ArP(1, aNE1); |
1299 | TColStd_Array1OfInteger ArI(1, aNE1); |
1300 | TopTools_ListIteratorOfListOfShape It (theListE);//pairs of edges |
1301 | //for (Standard_Integer i=1;It.More (); It.Next (),i++) { |
1302 | Standard_Integer i; |
1303 | for (i=1;It.More (); It.Next (),i++) { |
1304 | ArS.SetValue(i, It.Value ()); |
1305 | ArI.SetValue(i,0); |
1306 | ArP.SetValue(i, GetCenterPoint(It.Value())); |
1307 | } |
1308 | switch(aNE1) { |
1309 | case 2: |
1310 | // Identify position |
1311 | SortEdges2(ArP, theAx, ArI); |
1312 | break; |
1313 | case 3: |
1314 | SortEdges3(ArS, ArP, theAx, ArI); |
1315 | break; |
1316 | case 4: |
1317 | SortEdges4(ArS, ArP, theAx, ArI); |
1318 | break; |
1319 | case 5: |
1320 | SortEdges5(ArS, ArP, theAx, ArI); |
1321 | break; |
1322 | } |
1323 | |
1324 | for(i=1;i<=ArI.Upper();i++) { |
0797d9d3 |
1325 | #ifdef OCCT_DEBUG |
7fd59977 |
1326 | cout << "SortEdges: i = " <<i<<" ArI.Value(i) = " <<ArI.Value(i)<< endl; |
1327 | #endif |
1328 | theARS.SetValue(i, ArS.Value(ArI.Value(i))); |
1329 | |
1330 | } |
1331 | } |
1332 | //======================================================================= |
1333 | //function : LoadSymmetricalEdges |
1334 | //purpose : |
1335 | //======================================================================= |
1336 | |
1337 | void QANewBRepNaming_BooleanOperationFeat::LoadSymmetricalEdges (BRepAlgoAPI_BooleanOperation& MS) const |
1338 | { |
1339 | const TopoDS_Shape& aResult = MS.Shape(); |
1340 | if(aResult.IsNull()) return; |
1341 | const TopoDS_Shape& ObjSh = MS.Shape1(); |
1342 | const TopoDS_Shape& ToolSh = MS.Shape2(); |
1343 | const TopAbs_ShapeEnum& Type1 = ShapeType(ObjSh); |
1344 | if(Type1 == TopAbs_COMPOUND || Type1 > TopAbs_FACE) return; |
1345 | const TopAbs_ShapeEnum& Type2 = ShapeType(ToolSh); |
1346 | if(Type2 == TopAbs_COMPOUND || Type2 > TopAbs_FACE) return; |
1347 | TopTools_ListOfShape aList0; |
1348 | if (aResult.ShapeType() == TopAbs_COMPOUND) { |
1349 | TopoDS_Iterator itr(aResult); |
1350 | for (; itr.More(); itr.Next()) |
1351 | aList0.Append(itr.Value()); //collect separated entities (bodies) |
1352 | |
1353 | } |
1354 | if(aList0.Extent() > 2) return; // case > 2 ent. is not considered |
1355 | TopTools_ListOfShape aList1, aList2; |
1356 | TopTools_ListIteratorOfListOfShape It (aList0); //each item (body) must have at least 1 pair |
1357 | // of "cyl/con" surfaces (in some cases may be 3 or 4 faces depending on sim-edge position) |
1358 | for (;It.More (); It.Next ()) { |
1359 | const TopoDS_Shape& aShape = It.Value (); //1-st solid/shell |
1360 | TopTools_ListOfShape aList; |
1361 | aList.Clear(); |
0797d9d3 |
1362 | #ifdef OCCT_DEBUG |
7fd59977 |
1363 | // ModDbgTools_Write(aShape, "S0"); |
1364 | #endif |
1365 | if(aShape.ShapeType() != TopAbs_FACE) { |
1366 | TopExp_Explorer anExp(aShape, TopAbs_FACE); |
1367 | for(;anExp.More();anExp.Next()) { |
1368 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) |
1369 | aList.Append(anExp.Current()); // faces of the current entity |
1370 | } |
1371 | } else |
1372 | if(IsValidSurfType(TopoDS::Face(ObjSh))) |
1373 | aList.Append(aShape); |
1374 | |
1375 | if(aList1.Extent() == 0 ) |
1376 | aList1.Assign(aList); |
1377 | else |
1378 | aList2.Assign(aList); |
1379 | } |
1380 | // aList1,2 contain pairs of faces having more then 1 neghbour edge (each pair) |
1381 | const Standard_Integer aNF1 = aList1.Extent(); // keep n of faces of the first entity |
1382 | const Standard_Integer aNF2 = aList2.Extent(); // keep n of faces of the second entity |
1383 | if(aNF1 + aNF2 < 2) return; |
1384 | |
1385 | //find Edges |
1386 | TopTools_ListOfShape aListE1, aListE2; |
1387 | Standard_Integer aNE1=0,aNE2=0; |
1388 | if(aNF1 == 2 && !aNF2) {//trivial case - only 2 faces |
1389 | FindAdjacent2(aList1, aListE1); |
1390 | aNE1 = aListE1.Extent(); |
1391 | } |
1392 | else { // result is compound of two ent. |
1393 | if (aNF1 == 2) //first ent. has 2 valid faces |
1394 | FindAdjacent2(aList1, aListE1); // find adjacent edges |
1395 | else if (aNF1 == 3) // first ent. has 3 valid faces |
1396 | FindAdjacent3(aList1, aListE1); |
1397 | else if (aNF1 == 4) //first ent. has 4 valid faces |
1398 | FindAdjacent4(aList1, aListE1); |
1399 | // set number of symmetry Edges of the first ent. |
1400 | aNE1 = aListE1.Extent(); |
1401 | |
1402 | // Second ent. |
1403 | if (aNF2 == 2) //second ent. has 2 valid faces |
1404 | FindAdjacent2(aList2, aListE2); |
1405 | else if (aNF2 == 3) |
1406 | FindAdjacent3(aList2, aListE2); |
1407 | else if (aNF2 == 4) |
1408 | FindAdjacent4(aList2, aListE2); |
1409 | |
1410 | aNE2 = aListE2.Extent(); |
1411 | } |
1412 | //aListE1, aListE2 - contains Edges |
1413 | // if(aNE1 < 2) return; |
1414 | // check topological compatibility |
1415 | //if exist |
1416 | Handle(TDataStd_IntegerArray) aSAR; |
1417 | if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) { |
1418 | aSAR = TDataStd_IntegerArray::Set(ResultLabel(), 1, 2); |
1419 | aSAR->SetValue(1, 0); //tag num for faces structure |
1420 | aSAR->SetValue(2, 0); //tag num for edges structure |
1421 | } |
1422 | TDF_Label aLabelEDS; |
1423 | if(aSAR->Value(2)) aLabelEDS = ResultLabel().FindChild(aSAR->Value(2)); // !=0 |
1424 | else { |
1425 | // initial creation of EDS structure |
1426 | aLabelEDS = NewShapes(); |
1427 | aSAR->SetValue(2, aLabelEDS.Tag()); //keep tag |
1428 | } |
1429 | Handle(TDataStd_Integer) anAtt; |
1430 | if(aLabelEDS.FindAttribute(TDataStd_Integer::GetID(), anAtt) ) { |
1431 | // modification : check compatibility |
1432 | if(anAtt->Get() != aNE1+aNE2) { |
1433 | cout << "WARNING: Case isn't mantained - Number of Edges was changed!"<<endl; |
1434 | // mark all structure as Deleted |
1435 | Standard_Integer aN = aLabelEDS.Tag()+anAtt->Get(); |
1436 | for(Standard_Integer i=aLabelEDS.Tag(); i < aN; i++) { |
1437 | TDF_Label aLab = ResultLabel().FindChild(i, Standard_False); |
1438 | if(!aLab.IsNull()) { |
1439 | Handle(TNaming_NamedShape) aNS; |
1440 | if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { |
1441 | TopoDS_Shape aShape = aNS->Get(); |
1442 | TNaming_Builder aBuilder(aLab); |
1443 | aBuilder.Delete(aShape); //Deleted |
1444 | } |
1445 | } |
1446 | } |
1447 | // |
1448 | Handle(TDF_TagSource) aTS; |
1449 | ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS); |
1450 | if(!aTS.IsNull()) |
1451 | aTS->Set(aLabelEDS.Tag()); |
1452 | anAtt->Set(aNE1+aNE2); |
1453 | } |
1454 | |
1455 | } else |
1456 | TDataStd_Integer::Set(aLabelEDS, aNE1+aNE2); //keep number of edges |
1457 | |
1458 | // Identification |
1459 | // if(aNE1% 2 > 0) return; |
1460 | gp_Ax1 anAx = ComputeAxis(MS.Shape2()); |
1461 | Handle(TDF_TagSource) aTS; |
1462 | ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS); |
1463 | if(!aNE2 && aNE1) { // only 1 ent. |
1464 | //Top || Bot ? |
1465 | TopTools_Array1OfShape ArS1(1, aNE1); |
1466 | SortEdges(aListE1, anAx, ArS1); |
1467 | for(Standard_Integer i=1; i <= aNE1; i++) { |
1468 | TopoDS_Shape aShape = ArS1.Value(i); |
1469 | Standard_Integer aLabTag = aLabelEDS.Tag() + i -1; |
1470 | TDF_Label aLab = ResultLabel().FindChild(aLabTag); |
1471 | aTS->Set(aLabTag); |
1472 | TNaming_Builder aBuilder(aLab); |
1473 | aBuilder.Generated(aShape); |
1474 | } |
1475 | } else if(aNE1 && aNE2) { //2 ent. |
1476 | TopTools_Array1OfShape ArS1(1, aNE1); |
1477 | SortEdges(aListE1, anAx, ArS1); |
1478 | TopTools_Array1OfShape ArS2(1, aNE2); |
1479 | SortEdges(aListE2, anAx, ArS2); |
1480 | |
1481 | gp_Pnt aPnt1 = GetCenterPoint(aListE1.First()); |
1482 | // gp_Pnt aPnt2 = GetCenterPoint(aListE2.First()); |
1483 | if(IsDirectionPositive(anAx, anAx.Location(), aPnt1)) { |
1484 | Standard_Integer i; |
1485 | for(i=1; i <= aNE1; i++) { |
1486 | TopoDS_Shape aShape = ArS1.Value(i); |
1487 | Standard_Integer aLabTag = aLabelEDS.Tag() + i - 1; |
1488 | TDF_Label aLab = ResultLabel().FindChild(aLabTag); |
1489 | aTS->Set(aLabTag); |
1490 | TNaming_Builder aBuilder(aLab); |
1491 | aBuilder.Generated(aShape); |
1492 | } |
1493 | Standard_Integer start = aLabelEDS.Tag() + aNE1; |
1494 | for(i=1; i <= aNE2; i++) { |
1495 | TopoDS_Shape aShape = ArS2.Value(i); |
1496 | Standard_Integer aLabTag = start + i - 1; |
1497 | TDF_Label aLab = ResultLabel().FindChild(aLabTag); |
1498 | aTS->Set(aLabTag); |
1499 | TNaming_Builder aBuilder(aLab); |
1500 | aBuilder.Generated(aShape); |
1501 | } |
1502 | } |
1503 | else { |
1504 | Standard_Integer i; |
1505 | for(i=1; i <= aNE2; i++) { |
1506 | TopoDS_Shape aShape = ArS2.Value(i); |
1507 | Standard_Integer aLabTag = aLabelEDS.Tag() + i - 1; |
1508 | TDF_Label aLab = ResultLabel().FindChild(aLabTag); |
1509 | aTS->Set(aLabTag); |
1510 | TNaming_Builder aBuilder(aLab); |
1511 | aBuilder.Generated(aShape); |
1512 | } |
1513 | Standard_Integer start = aLabelEDS.Tag() + aNE2; |
1514 | for(i=1; i <= aNE1; i++) { |
1515 | TopoDS_Shape aShape = ArS1.Value(i); |
1516 | Standard_Integer aLabTag = start + i - 1; |
1517 | TDF_Label aLab = ResultLabel().FindChild(aLabTag); |
1518 | aTS->Set(aLabTag); |
1519 | TNaming_Builder aBuilder(aLab); |
1520 | aBuilder.Generated(aShape); |
1521 | } |
1522 | } |
1523 | } |
1524 | } |
1525 | |
1526 | //======================================================================= |
1527 | //function : ISWRCase2 |
1528 | //purpose : |
1529 | //======================================================================= |
1530 | Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsWRCase2(const BRepAlgoAPI_BooleanOperation& MS) { |
1531 | const TopoDS_Shape& Result = MS.Shape(); |
1532 | const TopAbs_ShapeEnum& ResType = ShapeType(Result); |
1533 | if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return Standard_False; |
1534 | TopTools_ListOfShape aList; |
1535 | |
1536 | TopExp_Explorer anExp(Result, TopAbs_FACE); |
1537 | for(;anExp.More();anExp.Next()) { |
1538 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) { |
1539 | TopExp_Explorer anExp1(Result, TopAbs_FACE); |
1540 | for(;anExp1.More();anExp1.Next()) { |
1541 | if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) { |
1542 | TopTools_ListOfShape aList; |
1543 | aList.Append(anExp.Current()); |
1544 | aList.Append(anExp1.Current()); |
1545 | TopTools_ListOfShape anEList; |
1546 | FindAdjacent2(aList, anEList); |
1547 | if(anEList.Extent() == 2) { |
1548 | return Standard_True; |
1549 | } |
1550 | } |
1551 | } |
1552 | } |
1553 | } |
deb26df7 |
1554 | return Standard_False; |
7fd59977 |
1555 | } |
1556 | |
1557 | //======================================================================= |
1558 | //function : LoadWRCase |
1559 | //purpose : |
1560 | //======================================================================= |
1561 | |
1562 | void QANewBRepNaming_BooleanOperationFeat::LoadWRCase(BRepAlgoAPI_BooleanOperation& MS) const { |
1563 | const TopoDS_Shape& Result = MS.Shape(); |
1564 | const TopAbs_ShapeEnum& ResType = ShapeType(Result); |
1565 | if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return; |
1566 | TopTools_ListOfShape aList; |
1567 | |
1568 | TopExp_Explorer anExp(Result, TopAbs_FACE); |
1569 | for(;anExp.More();anExp.Next()) { |
1570 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) { |
1571 | TopExp_Explorer anExp1(Result, TopAbs_FACE); |
1572 | for(;anExp1.More();anExp1.Next()) { |
1573 | if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) { |
1574 | TopTools_ListOfShape aList; |
1575 | aList.Append(anExp.Current()); |
1576 | aList.Append(anExp1.Current()); |
1577 | TopTools_ListOfShape anEList; |
1578 | FindAdjacent2(aList, anEList); |
1579 | if(anEList.Extent() == 2) { |
1580 | |
1581 | TopTools_ListIteratorOfListOfShape anEIt(anEList); |
1582 | GProp_GProps anE1Props, anE2Props; |
1583 | BRepGProp::LinearProperties(anEList.First(), anE1Props); |
1584 | BRepGProp::LinearProperties(anEList.Last(), anE2Props); |
1585 | |
1586 | const TDF_Label& WRE1Label = ResultLabel().NewChild(); |
1587 | const TDF_Label& WRE2Label = ResultLabel().NewChild(); |
1588 | const TDF_Label& WRV1Label = ResultLabel().NewChild(); |
1589 | const TDF_Label& WRV2Label = ResultLabel().NewChild(); |
0797d9d3 |
1590 | #ifdef OCCT_DEBUG |
7fd59977 |
1591 | TDataStd_Name::Set(WRE1Label, "WorkAroundEdge1"); |
1592 | TDataStd_Name::Set(WRE2Label, "WorkAroundEdge2"); |
1593 | TDataStd_Name::Set(WRV1Label, "WorkAroundVertex1"); |
1594 | TDataStd_Name::Set(WRV2Label, "WorkAroundVertex2"); |
1595 | #endif |
1596 | |
1597 | TNaming_Builder anEBuilder1(WRE1Label); |
1598 | TNaming_Builder anEBuilder2(WRE2Label); |
1599 | TNaming_Builder aVBuilder1(WRV1Label); |
1600 | TNaming_Builder aVBuilder2(WRV2Label); |
1601 | |
1602 | if(anE1Props.Mass() > anE2Props.Mass()) { |
1603 | anEBuilder1.Generated(anEList.Last()); |
1604 | anEBuilder2.Generated(anEList.First()); |
1605 | aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.Last()))); |
1606 | aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.Last()))); |
1607 | } else { |
1608 | anEBuilder1.Generated(anEList.First()); |
1609 | anEBuilder2.Generated(anEList.Last()); |
1610 | aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.First()))); |
1611 | aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.First()))); |
1612 | } |
1613 | } |
1614 | } |
1615 | } |
1616 | } |
1617 | } |
1618 | } |