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