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