1 // Created on: 1999-09-27
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_HCurve.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepAlgoAPI_BooleanOperation.hxx>
22 #include <BRepGProp.hxx>
23 #include <Geom_Ellipse.hxx>
24 #include <GeomAbs_SurfaceType.hxx>
26 #include <gp_Cone.hxx>
27 #include <gp_Cylinder.hxx>
28 #include <GProp_GProps.hxx>
29 #include <Precision.hxx>
30 #include <QANewBRepNaming_BooleanOperation.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>
36 #include <TDataStd_Integer.hxx>
37 #include <TDataStd_IntegerArray.hxx>
38 #include <TDataStd_Name.hxx>
39 #include <TDataStd_Real.hxx>
40 #include <TDF_Label.hxx>
41 #include <TDF_TagSource.hxx>
42 #include <TNaming_Builder.hxx>
43 #include <TNaming_NamedShape.hxx>
45 #include <TopExp_Explorer.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>
57 #include <TDataStd_Name.hxx>
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)
70 save << "DBRep_DrawableShape" << endl << endl;
71 if(!shape.IsNull()) BRepTools::Write(shape, save);
77 //=======================================================================
78 //function : QANewBRepNaming_BooleanOperation
80 //=======================================================================
82 QANewBRepNaming_BooleanOperation::QANewBRepNaming_BooleanOperation() {}
84 //=======================================================================
85 //function : QANewBRepNaming_BooleanOperation
87 //=======================================================================
89 QANewBRepNaming_BooleanOperation::QANewBRepNaming_BooleanOperation(const TDF_Label& ResultLabel):QANewBRepNaming_TopNaming(ResultLabel) {}
91 //=======================================================================
94 //=======================================================================
96 void QANewBRepNaming_BooleanOperation::Init(const TDF_Label& ResultLabel) {
97 if(ResultLabel.IsNull())
98 throw Standard_NullObject("QANewBRepNaming_BooleanOperation::Init The Result label is Null ...");
99 myResultLabel = ResultLabel;
102 //=======================================================================
103 //function : ModifiedFaces
105 //=======================================================================
107 TDF_Label QANewBRepNaming_BooleanOperation::ModifiedFaces() const {
109 const TDF_Label& ModifiedFacesLabel = ResultLabel().NewChild();
110 TDataStd_Name::Set(ModifiedFacesLabel, "ModifiedFaces");
111 return ModifiedFacesLabel;
113 return ResultLabel().NewChild();
117 //=======================================================================
118 //function : ModifiedEdges
120 //=======================================================================
122 TDF_Label QANewBRepNaming_BooleanOperation::ModifiedEdges() const {
124 const TDF_Label& ModifiedEdgesLabel = ResultLabel().NewChild();
125 TDataStd_Name::Set(ModifiedEdgesLabel, "ModifiedEdges");
126 return ModifiedEdgesLabel;
128 return ResultLabel().NewChild();
132 //=======================================================================
133 //function : DeletedFaces
135 //=======================================================================
137 TDF_Label QANewBRepNaming_BooleanOperation::DeletedFaces() const {
139 const TDF_Label& DeletedFacesLabel = ResultLabel().NewChild();
140 TDataStd_Name::Set(DeletedFacesLabel, "DeletedFaces");
141 return DeletedFacesLabel;
143 return ResultLabel().NewChild();
147 //=======================================================================
148 //function : DeletedEdges
150 //=======================================================================
152 TDF_Label QANewBRepNaming_BooleanOperation::DeletedEdges() const {
154 const TDF_Label& DeletedEdgesLabel = ResultLabel().NewChild();
155 TDataStd_Name::Set(DeletedEdgesLabel, "DeletedEdges");
156 return DeletedEdgesLabel;
158 return ResultLabel().NewChild();
162 //=======================================================================
163 //function : DeletedVertices
165 //=======================================================================
167 TDF_Label QANewBRepNaming_BooleanOperation::DeletedVertices() const {
169 const TDF_Label& DeletedVerticesLabel = ResultLabel().NewChild();
170 TDataStd_Name::Set(DeletedVerticesLabel, "DeletedVertices");
171 return DeletedVerticesLabel;
173 return ResultLabel().NewChild();
177 //=======================================================================
178 //function : NewShapes
180 //=======================================================================
182 TDF_Label QANewBRepNaming_BooleanOperation::NewShapes() const {
184 const TDF_Label& NewShapesLabel = ResultLabel().NewChild();
185 TDataStd_Name::Set(NewShapesLabel, "NewShapes");
186 return NewShapesLabel;
188 return ResultLabel().NewChild();
192 //=======================================================================
195 //=======================================================================
197 TDF_Label QANewBRepNaming_BooleanOperation::Content() const {
199 const TDF_Label& ContentLabel = ResultLabel().NewChild();
200 TDataStd_Name::Set(ContentLabel, "Content");
203 return ResultLabel().NewChild();
207 //=======================================================================
208 //function : DeletedDegeneratedEdges
210 //=======================================================================
212 TDF_Label QANewBRepNaming_BooleanOperation::DeletedDegeneratedEdges() const {
214 const TDF_Label& DegeneratedLabel = ResultLabel().NewChild();
215 TDataStd_Name::Set(DegeneratedLabel, "DeletedDegeneratedEdges");
216 return DegeneratedLabel;
218 return ResultLabel().NewChild();
222 //=======================================================================
223 //function : ShapeType
225 //=======================================================================
227 TopAbs_ShapeEnum QANewBRepNaming_BooleanOperation::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;
235 for(; itr.More(); itr.Next())
236 if(ShapeType(itr.Value()) != TypeSh) return TopAbs_COMPOUND;
241 //=======================================================================
242 //function : GetShape
244 //=======================================================================
246 TopoDS_Shape QANewBRepNaming_BooleanOperation::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();
254 //=======================================================================
255 //function : LoadWire
257 //=======================================================================
259 void QANewBRepNaming_BooleanOperation::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);
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);
270 // Naming of deleted edges, dangle vertices
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);
279 //=======================================================================
280 //function : LoadShell
282 //=======================================================================
284 void QANewBRepNaming_BooleanOperation::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);
291 if(MS.HasGenerated()) {
292 TNaming_Builder nBuilder (NewShapes());
294 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder);
295 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_FACE, nBuilder);
297 // Naming of deleted faces edges:
299 TNaming_Builder DelFBuilder(DeletedFaces());
300 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_FACE, DelFBuilder);
302 TNaming_Builder DelEBuilder(DeletedEdges());
303 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder);
307 //=======================================================================
308 //function : LoadContent
310 //=======================================================================
312 void QANewBRepNaming_BooleanOperation::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;
321 for (itr.Initialize(MS.Shape()); itr.More(); itr.Next()) {
322 TNaming_Builder bContent(Content());
323 bContent.Generated(itr.Value());
329 //=======================================================================
330 //function : LoadResult
332 //=======================================================================
334 void QANewBRepNaming_BooleanOperation::LoadResult(BRepAlgoAPI_BooleanOperation& MS) const {
335 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
336 if (Tagger.IsNull()) return;
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();
349 if (MS.Shape1().IsNull()) Builder.Generated(aResult);
350 else Builder.Modify(MS.Shape1(), aResult);
353 //=======================================================================
354 //function : LoadDegenerated
356 //=======================================================================
358 void QANewBRepNaming_BooleanOperation::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));
368 TDataStd_Name::Set(DegeneratedBuilder.NamedShape()->Label(), "DeletedDegenerated");
375 //=======================================================================
376 //function : IsResultChanged
378 //=======================================================================
380 Standard_Boolean QANewBRepNaming_BooleanOperation::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();
391 return MS.Shape1().IsSame(ResSh);
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;
407 else if(aType == GeomAbs_SurfaceOfExtrusion) {
408 aBasisCurve = anAdapt.BasisCurve();
409 if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse)
410 return Standard_True;
413 ModDbgTools_Write(theFace, "Surf");
415 return Standard_False;
417 //=======================================================================
418 //function : IsWRCase
420 //=======================================================================
422 Standard_Boolean QANewBRepNaming_BooleanOperation::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;
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());
439 if(IsValidSurfType(TopoDS::Face(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());
449 if(IsValidSurfType(TopoDS::Face(ToolSh)))
450 aList.Append(ToolSh);
451 if(aList.Extent() == 2) return Standard_True;
453 return Standard_False;
456 //=======================================================================
457 static gp_Ax1 ComputeAxis(const TopoDS_Shape& theShape) {
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();
481 //==============================================================================
483 //==========================================================================
484 static Standard_Integer Identify(const TopoDS_Face& theFace, const gp_Ax1& theAx) {
486 BRepGProp::SurfaceProperties(theFace, aGProp);
487 gp_Pnt aPoint = aGProp.CentreOfMass();
488 gp_Vec aV1(theAx.Direction());
489 gp_Vec aV2(theAx.Location(), aPoint);
491 gp_Vec v1 = aV1.Crossed(aV2);
492 cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
494 if((aV1.Crossed(aV2)).XYZ().Z() >= 0) return 1; //right orientation
495 return (-1); //left orientation
498 //=======================================================================
499 //function : LoadModified11
501 //=======================================================================
503 void QANewBRepNaming_BooleanOperation::LoadModified11 (BRepAlgoAPI_BooleanOperation& MS,
504 const TopoDS_Shape& ShapeIn,
505 const TopAbs_ShapeEnum KindOfShape) const
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;
514 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
515 if(Shapes.Extent() == 1) {found = Standard_True; break;}
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;
525 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
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)
533 TCollection_AsciiString entry;
534 TDF_Tool::Entry(Builder.NamedShape()->Label(), entry);
535 cout << "Add shape to Compound at Label = "<< entry <<endl;
537 Builder.Modify (Root,newShape);
543 //======================================================================
544 static gp_Pnt GetCenterPoint(const TopoDS_Shape& theEdge)
547 BRepGProp::LinearProperties(theEdge, aGProp);
548 return aGProp.CentreOfMass();
550 //===================================================================
551 static void SortRootFaces(TopTools_ListOfShape& theList, const TopoDS_Shape& theShape)
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);
562 for(i=1;It.More();It.Next(),i++) {
563 ArS.SetValue(i, It.Value ());
565 ArP.SetValue(i, GetCenterPoint(It.Value()));
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));
574 for(i=1;i <= aNum; i++) {
576 if(ArI.Value(i) == -1) continue;
577 Standard_Real aD2 = aPnt.Distance(ArP(i));
583 if (I == 0) continue;
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));
591 theList.Assign(aList);
593 //=======================================================================
594 static void Sort2Faces(const TopTools_ListOfShape& Shapes,
595 const gp_Ax1& theAx, TopTools_ListOfShape& theList)
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
606 //=======================================================================
607 static void Sort3Faces(const TopTools_ListOfShape& theListIn, TopTools_ListOfShape& theListOut)
609 TopTools_ListIteratorOfListOfShape It (theListIn);
610 TopTools_Array1OfShape ArS(1, theListIn.Extent());
611 TColgp_Array1OfPnt ArP(1, theListIn.Extent());
614 for(i=1;It.More();It.Next(),i++) {
615 ArS.SetValue(i, It.Value());
616 ArP.SetValue(i, GetCenterPoint(It.Value()));
619 Standard_Boolean found = Standard_False;
620 Standard_Integer j, i1 = 0, i2 = 0, i3 = 0;
623 TopExp_Explorer anExp1(ArS.Value(i), TopAbs_EDGE);
624 for(;anExp1.More();anExp1.Next()) {
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());
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
663 theListOut.Append(ArS.Value(i1));
664 theListOut.Append(ArS.Value(i2));
665 theListOut.Append(ArS.Value(i3)); //single
667 //=======================================================================
668 //function : Load1nFaces
670 //=======================================================================
672 void QANewBRepNaming_BooleanOperation::Load1nFaces(BRepAlgoAPI_BooleanOperation& MS, const TopoDS_Shape& ShapeIn) const
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;
681 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
682 if(Shapes.Extent() < 2) continue;
685 if(ShapeIn.IsEqual(MS.Shape1()))
686 if(aListR.Extent() > 1) SortRootFaces(aListR, ShapeIn);
688 TopTools_ListIteratorOfListOfShape Itr(aListR);
689 for(;Itr.More();Itr.Next()) {
690 const TopoDS_Shape& Root = Itr.Value();
691 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
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 ());
707 //=======================================================================
708 //function : LoadModified faces
709 //purpose : 1 : n modification
710 //=======================================================================
712 void QANewBRepNaming_BooleanOperation::LoadModified1n (BRepAlgoAPI_BooleanOperation& MS,
713 const TopoDS_Shape& ShapeIn,
714 const TopAbs_ShapeEnum KindOfShape) const
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;
724 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
725 if(Shapes.Extent() >= 2) aNum += Shapes.Extent();
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;
734 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
735 if(Shapes.Extent() >= 2) aNum += Shapes.Extent();
738 Handle(TDataStd_IntegerArray) aSAR;
739 if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) {
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
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) )
752 TDF_Label aFLab = ResultLabel().FindChild(aLab.Tag() + aNE);
753 if(!aFLab.FindAttribute(TDataStd_Integer::GetID(), anAtt))
754 aSAR->SetValue(1, 0);
758 aLabelFDS = ResultLabel().FindChild(aSAR->Value(1)); // !=0 -already exist
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);
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);
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
787 Handle(TDF_TagSource) aTS;
788 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
790 aTS->Set(aLabelFDS.Tag());
794 TDataStd_Integer::Set(aLabelFDS, aNum); //keep number of faces
796 Load1nFaces(MS, ShapeIn);
797 Load1nFaces(MS, Tool);
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);
808 // gp_Vec v1 = aVec1.Crossed(aVec2);
809 // cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
811 if((aVec1.Crossed(aVec2)).XYZ().Z() >= 0) isPositive = Standard_True;
813 isPositive = Standard_False;
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)
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));
827 theArI.SetValue(1, 1);
828 theArI.SetValue(2, 2);
830 theArI.SetValue(1, 2); //change order
831 theArI.SetValue(2, 1);
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)
840 Standard_Integer i, j, i1 = 0,i2 = 0, i3 = 0;
842 Standard_Boolean adjacent = Standard_False;
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;}
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;}
855 Standard_Integer aSum = i+j;
858 i1 = 3;i2 = 1;i3 = 2;
861 i1 = 2; i2 = 1;i3 = 3;
864 i1 = 1; i2 = 2;i3 = 3;
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
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
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
890 Standard_Integer aN = i3; i3 = i2;
895 theArI.SetValue(1, i1);
896 theArI.SetValue(2, i2);
897 theArI.SetValue(3, i3);
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)
906 // 1. find adjacent edges, build pairs in ArI
907 // 2. find nearest pair, reorganize ArI
908 // 3. sort inside pairs
909 // =======================================
910 Standard_Integer i, j, i1 = 0,i2 = 0, i3 = 0, i4 = 0;
914 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
915 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
916 Standard_Boolean aDjacent = Standard_False;
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;}
924 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV12;}
926 aDjacent = Standard_True;
927 Standard_Integer aSum = i+j;
945 // i1,i2 - first pair of adjacent: aV1.
946 // i3,i4 - next pair of adjacent: aV2.
947 // find agjacent V (i3-i4)
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;
954 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i3)));
955 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV2 = aV12;
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;
972 // pair of adjacent i1-i2 is the nearest
975 // 3. sort inside pairs
976 if(!IsDirectionPositive(theAx, aCP1, theArP.Value(i1))) {//first must be positive direction
978 Standard_Integer aN = i2; i2 = i1;
982 if(!IsDirectionPositive(theAx, aCP2, theArP.Value(i3))) {//first must be positive direction
985 cout << "SortEdges4: i3 = "<<i3<< "i4 = "<< i4 << endl;
987 Standard_Integer aN = i4; i4 = i3;
991 // 4. final order i1, i2, i3, i4 - Ok
993 cout << "SortEdges4: i1 = " <<i1<<" i2 = "<<i2<< " i3 = "<<i3<< "i4 = "<< i4 << endl;
995 theArI.SetValue(1, i1);
996 theArI.SetValue(2, i2);
997 theArI.SetValue(3, i3);
998 theArI.SetValue(4, i4);
1000 // ======================================================================
1001 static void SortEdges5 (const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP,
1002 const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI)
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;
1013 TopoDS_Shape aV1, aV2, aV;
1014 Standard_Integer I=0, J1=0, J2=0;
1016 Standard_Boolean found = Standard_False;
1017 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
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;
1029 found = Standard_False;
1030 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
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)) {
1038 if(I != i) cout << "WARNING:: I != i, I = " << I << ", i = " << i <<endl;
1040 found = Standard_True;
1047 // aV1, aV2 - vetexes of middle Edge, I - index of middle Edge, J1, J2 = indexes of
1048 // adjacent edges of the middle edge
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;
1058 // find agjacent V (i4-i5)
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;
1065 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4)));
1066 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV3 = aV12;
1069 // 2. find nearest group (aV1, aV3), reorganize ArI - nerest => top
1070 gp_Pnt aDP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1));
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
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
1085 // goup of 2 edges i1-i2 is the nearest
1087 // 3.1. sort inside group of 2 edges
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;
1103 // 3.2. sort inside group of 3 edges
1106 aDP = theArP.Value(i4); //center of middle edge
1107 aCP = theArP.Value(i3);
1110 aDP = theArP.Value(i2);
1111 aCP = theArP.Value(i1);
1114 if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction
1115 Standard_Integer aN;
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);
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());
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());
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());
1164 Standard_Boolean aDjacent = Standard_False;
1165 Standard_Integer j, i2 = 0, i3 = 0; //i2, i3 - indexes of two adjacent faces having the same surface
1166 Standard_Integer i1 = 0; //single face
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;
1176 i1 = 3; i2 = 1; i3 = 2;
1179 i1 = 2; i2 = 1; i3 = 3;
1182 i1 = 1; i2 = 2; i3 = 3;
1185 i1 = 1; i2 = 2; i3 = 3;
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;}
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;}
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());
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());
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;
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;
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;}
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;}
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;}
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;}
1290 //=======================================================================
1291 // SortEdges: returns
1292 //=======================================================================
1293 static void SortEdges(const TopTools_ListOfShape& theListE, const gp_Ax1& theAx,
1294 TopTools_Array1OfShape& theARS)
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++) {
1304 for (i=1;It.More (); It.Next (),i++) {
1305 ArS.SetValue(i, It.Value ());
1307 ArP.SetValue(i, GetCenterPoint(It.Value()));
1311 // Identify position
1312 SortEdges2(ArP, theAx, ArI);
1315 SortEdges3(ArS, ArP, theAx, ArI);
1318 SortEdges4(ArS, ArP, theAx, ArI);
1321 SortEdges5(ArS, ArP, theAx, ArI);
1325 for(i=1;i<=ArI.Upper();i++) {
1327 cout << "SortEdges: i = " <<i<<" ArI.Value(i) = " <<ArI.Value(i)<< endl;
1329 theARS.SetValue(i, ArS.Value(ArI.Value(i)));
1333 //=======================================================================
1334 //function : LoadSymmetricalEdges
1336 //=======================================================================
1338 void QANewBRepNaming_BooleanOperation::LoadSymmetricalEdges (BRepAlgoAPI_BooleanOperation& MS) const
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)
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;
1364 // ModDbgTools_Write(aShape, "S0");
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
1373 if(IsValidSurfType(TopoDS::Face(ObjSh)))
1374 aList.Append(aShape);
1376 if(aList1.Extent() == 0 )
1377 aList1.Assign(aList);
1379 aList2.Assign(aList);
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;
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();
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();
1404 if (aNF2 == 2) //second ent. has 2 valid faces
1405 FindAdjacent2(aList2, aListE2);
1407 FindAdjacent3(aList2, aListE2);
1409 FindAdjacent4(aList2, aListE2);
1411 aNE2 = aListE2.Extent();
1413 //aListE1, aListE2 - contains Edges
1414 // if(aNE1 < 2) return;
1415 // check topological compatibility
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
1423 TDF_Label aLabelEDS;
1424 if(aSAR->Value(2)) aLabelEDS = ResultLabel().FindChild(aSAR->Value(2)); // !=0
1426 // initial creation of EDS structure
1427 aLabelEDS = NewShapes();
1428 aSAR->SetValue(2, aLabelEDS.Tag()); //keep tag
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
1449 Handle(TDF_TagSource) aTS;
1450 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
1452 aTS->Set(aLabelEDS.Tag());
1453 anAtt->Set(aNE1+aNE2);
1457 TDataStd_Integer::Set(aLabelEDS, aNE1+aNE2); //keep number of edges
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.
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);
1473 TNaming_Builder aBuilder(aLab);
1474 aBuilder.Generated(aShape);
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);
1482 gp_Pnt aPnt1 = GetCenterPoint(aListE1.First());
1483 // gp_Pnt aPnt2 = GetCenterPoint(aListE2.First());
1484 if(IsDirectionPositive(anAx, anAx.Location(), aPnt1)) {
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);
1491 TNaming_Builder aBuilder(aLab);
1492 aBuilder.Generated(aShape);
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);
1500 TNaming_Builder aBuilder(aLab);
1501 aBuilder.Generated(aShape);
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);
1511 TNaming_Builder aBuilder(aLab);
1512 aBuilder.Generated(aShape);
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);
1520 TNaming_Builder aBuilder(aLab);
1521 aBuilder.Generated(aShape);
1527 //=======================================================================
1528 //function : ISWRCase2
1530 //=======================================================================
1531 Standard_Boolean QANewBRepNaming_BooleanOperation::IsWRCase2(BRepAlgoAPI_BooleanOperation& MS) {
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;
1536 TopExp_Explorer anExp(Result, TopAbs_FACE);
1537 for(;anExp.More();anExp.Next()) {
1538 if(IsValidSurfType(TopoDS::Face(anExp.Current()))) {
1539 TopExp_Explorer anExp1(Result, TopAbs_FACE);
1540 for(;anExp1.More();anExp1.Next()) {
1541 if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) {
1542 TopTools_ListOfShape aList;
1543 aList.Append(anExp.Current());
1544 aList.Append(anExp1.Current());
1545 TopTools_ListOfShape anEList;
1546 FindAdjacent2(aList, anEList);
1547 if(anEList.Extent() == 2) {
1548 return Standard_True;
1554 return Standard_False;
1557 //=======================================================================
1558 //function : LoadWRCase
1560 //=======================================================================
1562 void QANewBRepNaming_BooleanOperation::LoadWRCase(BRepAlgoAPI_BooleanOperation& MS) const {
1563 const TopoDS_Shape& Result = MS.Shape();
1564 const TopAbs_ShapeEnum& ResType = ShapeType(Result);
1565 if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return;
1567 TopExp_Explorer anExp(Result, TopAbs_FACE);
1568 for(;anExp.More();anExp.Next()) {
1569 if(IsValidSurfType(TopoDS::Face(anExp.Current()))) {
1570 TopExp_Explorer anExp1(Result, TopAbs_FACE);
1571 for(;anExp1.More();anExp1.Next()) {
1572 if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) {
1573 TopTools_ListOfShape aList;
1574 aList.Append(anExp.Current());
1575 aList.Append(anExp1.Current());
1576 TopTools_ListOfShape anEList;
1577 FindAdjacent2(aList, anEList);
1578 if(anEList.Extent() == 2) {
1580 TopTools_ListIteratorOfListOfShape anEIt(anEList);
1581 GProp_GProps anE1Props, anE2Props;
1582 BRepGProp::LinearProperties(anEList.First(), anE1Props);
1583 BRepGProp::LinearProperties(anEList.Last(), anE2Props);
1585 const TDF_Label& WRE1Label = ResultLabel().NewChild();
1586 const TDF_Label& WRE2Label = ResultLabel().NewChild();
1587 const TDF_Label& WRV1Label = ResultLabel().NewChild();
1588 const TDF_Label& WRV2Label = ResultLabel().NewChild();
1590 TDataStd_Name::Set(WRE1Label, "WorkAroundEdge1");
1591 TDataStd_Name::Set(WRE2Label, "WorkAroundEdge2");
1592 TDataStd_Name::Set(WRV1Label, "WorkAroundVertex1");
1593 TDataStd_Name::Set(WRV2Label, "WorkAroundVertex2");
1596 TNaming_Builder anEBuilder1(WRE1Label);
1597 TNaming_Builder anEBuilder2(WRE2Label);
1598 TNaming_Builder aVBuilder1(WRV1Label);
1599 TNaming_Builder aVBuilder2(WRV2Label);
1601 if(anE1Props.Mass() > anE2Props.Mass()) {
1602 anEBuilder1.Generated(anEList.Last());
1603 anEBuilder2.Generated(anEList.First());
1604 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.Last())));
1605 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.Last())));
1607 anEBuilder1.Generated(anEList.First());
1608 anEBuilder2.Generated(anEList.Last());
1609 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.First())));
1610 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.First())));