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
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.
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.
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.
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>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_IndexedMapOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
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>
57 #include <QANewBRepNaming_Loader.hxx>
60 #include <TDataStd_Name.hxx>
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)
73 save << "DBRep_DrawableShape" << endl << endl;
74 if(!shape.IsNull()) BRepTools::Write(shape, save);
78 static void ModDbgTools_WriteCurrentShape(const Handle(TNaming_NamedShape) & NS)
80 TCollection_AsciiString entry;
81 TDF_Tool::Entry(NS->Label(), entry);
84 TopoDS_Shape Sh = TNaming_Tool::CurrentShape (NS);
86 TCollection_AsciiString Entry = entry.Cat("_Cur.brep");
87 ModDbgTools_Write(Sh, Entry.ToCString());
90 cout << "ModDbgTools::Write>>> TopoDS_Shape IS NULL on Entry = "<< entry << endl;
93 cout << "ModDbgTools::Write>>> CurrentShape of TNaming_NamedShape IS NULL on Entry = "<< entry << endl;
97 //=======================================================================
98 //function : QANewBRepNaming_BooleanOperationFeat
100 //=======================================================================
102 QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat() {}
104 //=======================================================================
105 //function : QANewBRepNaming_BooleanOperationFeat
107 //=======================================================================
109 QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat(const TDF_Label& ResultLabel):QANewBRepNaming_TopNaming(ResultLabel) {}
111 //=======================================================================
114 //=======================================================================
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;
122 //=======================================================================
123 //function : ModifiedFaces
125 //=======================================================================
127 TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedFaces() const {
129 const TDF_Label& ModifiedFacesLabel = ResultLabel().NewChild();
130 TDataStd_Name::Set(ModifiedFacesLabel, "ModifiedFaces");
131 return ModifiedFacesLabel;
133 return ResultLabel().NewChild();
136 //=======================================================================
137 //function : ModifiedEdges
139 //=======================================================================
141 TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedEdges() const {
143 const TDF_Label& ModifiedEdgesLabel = ResultLabel().NewChild();
144 TDataStd_Name::Set(ModifiedEdgesLabel, "ModifiedEdges");
145 return ModifiedEdgesLabel;
147 return ResultLabel().NewChild();
150 //=======================================================================
151 //function : DeletedFaces
153 //=======================================================================
155 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedFaces() const {
157 const TDF_Label& DeletedFacesLabel = ResultLabel().NewChild();
158 TDataStd_Name::Set(DeletedFacesLabel, "DeletedFaces");
159 return DeletedFacesLabel;
161 return ResultLabel().NewChild();
164 //=======================================================================
165 //function : DeletedEdges
167 //=======================================================================
169 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedEdges() const {
171 const TDF_Label& DeletedEdgesLabel = ResultLabel().NewChild();
172 TDataStd_Name::Set(DeletedEdgesLabel, "DeletedEdges");
173 return DeletedEdgesLabel;
175 return ResultLabel().NewChild();
178 //=======================================================================
179 //function : DeletedVertices
181 //=======================================================================
183 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedVertices() const {
185 const TDF_Label& DeletedVerticesLabel = ResultLabel().NewChild();
186 TDataStd_Name::Set(DeletedVerticesLabel, "DeletedVertices");
187 return DeletedVerticesLabel;
189 return ResultLabel().NewChild();
192 //=======================================================================
193 //function : NewShapes
195 //=======================================================================
197 TDF_Label QANewBRepNaming_BooleanOperationFeat::NewShapes() const {
199 const TDF_Label& NewShapesLabel = ResultLabel().NewChild();
200 TDataStd_Name::Set(NewShapesLabel, "NewShapes");
201 return NewShapesLabel;
203 return ResultLabel().NewChild();
206 //=======================================================================
209 //=======================================================================
211 TDF_Label QANewBRepNaming_BooleanOperationFeat::Content() const {
213 const TDF_Label& ContentLabel = ResultLabel().NewChild();
214 TDataStd_Name::Set(ContentLabel, "Content");
217 return ResultLabel().NewChild();
220 //=======================================================================
221 //function : DeletedDegeneratedEdges
223 //=======================================================================
225 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedDegeneratedEdges() const {
227 const TDF_Label& DegeneratedLabel = ResultLabel().NewChild();
228 TDataStd_Name::Set(DegeneratedLabel, "DeletedDegeneratedEdges");
229 return DegeneratedLabel;
231 return ResultLabel().NewChild();
234 //=======================================================================
235 //function : ShapeType
237 //=======================================================================
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;
247 for(; itr.More(); itr.Next())
248 if(ShapeType(itr.Value()) != TypeSh) return TopAbs_COMPOUND;
253 //=======================================================================
254 //function : GetShape
256 //=======================================================================
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();
266 //=======================================================================
267 //function : LoadWire
269 //=======================================================================
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);
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);
282 // Naming of deleted edges, dangle vertices
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);
291 //=======================================================================
292 //function : LoadShell
294 //=======================================================================
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);
303 if(MS.HasGenerated()) {
304 TNaming_Builder nBuilder (NewShapes());
306 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder);
307 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_FACE, nBuilder);
309 // Naming of deleted faces edges:
311 TNaming_Builder DelFBuilder(DeletedFaces());
312 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_FACE, DelFBuilder);
314 TNaming_Builder DelEBuilder(DeletedEdges());
315 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder);
319 //=======================================================================
320 //function : LoadContent
322 //=======================================================================
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;
333 for (itr.Initialize(MS.Shape()); itr.More(); itr.Next()) {
334 TNaming_Builder bContent(Content());
335 bContent.Generated(itr.Value());
341 //=======================================================================
342 //function : LoadResult
344 //=======================================================================
346 void QANewBRepNaming_BooleanOperationFeat::LoadResult(BRepAlgoAPI_BooleanOperation& MS) const {
347 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
348 if (Tagger.IsNull()) return;
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();
361 if (MS.Shape1().IsNull()) Builder.Generated(aResult);
362 else Builder.Modify(MS.Shape1(), aResult);
365 //=======================================================================
366 //function : LoadDegenerated
368 //=======================================================================
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));
380 TDataStd_Name::Set(DegeneratedBuilder.NamedShape()->Label(), "DeletedDegenerated");
387 //=======================================================================
388 //function : IsResultChanged
390 //=======================================================================
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();
403 return MS.Shape1().IsSame(ResSh);
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;
419 else if(aType == GeomAbs_SurfaceOfExtrusion) {
420 aBasisCurve = anAdapt.BasisCurve();
421 if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse)
422 return Standard_True;
425 ModDbgTools_Write(theFace, "Surf");
427 return Standard_False;
429 //=======================================================================
430 //function : IsWRCase
432 //=======================================================================
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;
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());
451 if(IsValidSurfType(TopoDS::Face(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());
461 if(IsValidSurfType(TopoDS::Face(ToolSh)))
462 aList.Append(ToolSh);
463 if(aList.Extent() == 2) return Standard_True;
465 return Standard_False;
468 //=======================================================================
469 static gp_Ax1 ComputeAxis(const TopoDS_Shape& theShape) {
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();
493 //==============================================================================
495 //==========================================================================
496 static Standard_Integer Identify(const TopoDS_Face& theFace, const gp_Ax1& theAx) {
498 BRepGProp::SurfaceProperties(theFace, aGProp);
499 gp_Pnt aPoint = aGProp.CentreOfMass();
500 gp_Vec aV1(theAx.Direction());
501 gp_Vec aV2(theAx.Location(), aPoint);
503 gp_Vec v1 = aV1.Crossed(aV2);
504 cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
506 if((aV1.Crossed(aV2)).XYZ().Z() >= 0) return 1; //right orientation
507 return (-1); //left orientation
510 //=======================================================================
511 //function : LoadModified11
513 //=======================================================================
515 void QANewBRepNaming_BooleanOperationFeat::LoadModified11 (BRepAlgoAPI_BooleanOperation& MS,
516 const TopoDS_Shape& ShapeIn,
517 const TopAbs_ShapeEnum KindOfShape) const
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;}
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)
545 TCollection_AsciiString entry;
546 TDF_Tool::Entry(Builder.NamedShape()->Label(), entry);
547 cout << "Add shape to Compound at Label = "<< entry <<endl;
549 Builder.Modify (Root,newShape);
555 //======================================================================
556 static gp_Pnt GetCenterPoint(const TopoDS_Shape& theEdge)
559 BRepGProp::LinearProperties(theEdge, aGProp);
560 return aGProp.CentreOfMass();
562 //===================================================================
563 static void SortRootFaces(TopTools_ListOfShape& theList, const TopoDS_Shape& theShape)
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);
574 for(i=1;It.More();It.Next(),i++) {
575 ArS.SetValue(i, It.Value ());
577 ArP.SetValue(i, GetCenterPoint(It.Value()));
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));
586 for(i=1;i <= aNum; i++) {
588 if(ArI.Value(i) == -1) continue;
589 Standard_Real aD2 = aPnt.Distance(ArP(i));
595 if (I == 0) continue;
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));
603 theList.Assign(aList);
605 //=======================================================================
606 static void Sort2Faces(const TopTools_ListOfShape& Shapes,
607 const gp_Ax1& theAx, TopTools_ListOfShape& theList)
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
618 //=======================================================================
619 static void Sort3Faces(const TopTools_ListOfShape& theListIn, TopTools_ListOfShape& theListOut)
621 TopTools_ListIteratorOfListOfShape It (theListIn);
622 TopTools_Array1OfShape ArS(1, theListIn.Extent());
623 TColgp_Array1OfPnt ArP(1, theListIn.Extent());
626 for(i=1;It.More();It.Next(),i++) {
627 ArS.SetValue(i, It.Value());
628 ArP.SetValue(i, GetCenterPoint(It.Value()));
631 Standard_Boolean found = Standard_False;
632 Standard_Integer j, i1, i2, i3;
635 TopExp_Explorer anExp1(ArS.Value(i), TopAbs_EDGE);
636 for(;anExp1.More();anExp1.Next()) {
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());
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
675 theListOut.Append(ArS.Value(i1));
676 theListOut.Append(ArS.Value(i2));
677 theListOut.Append(ArS.Value(i3)); //single
679 //=======================================================================
680 //function : Load1nFaces
682 //=======================================================================
684 void QANewBRepNaming_BooleanOperationFeat::Load1nFaces(BRepAlgoAPI_BooleanOperation& MS, const TopoDS_Shape& ShapeIn) const
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;
697 if(ShapeIn.IsEqual(MS.Shape1()))
698 if(aListR.Extent() > 1) SortRootFaces(aListR, ShapeIn);
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 ());
719 //=======================================================================
720 //function : LoadModified faces
721 //purpose : 1 : n modification
722 //=======================================================================
724 void QANewBRepNaming_BooleanOperationFeat::LoadModified1n (BRepAlgoAPI_BooleanOperation& MS,
725 const TopoDS_Shape& ShapeIn,
726 const TopAbs_ShapeEnum KindOfShape) const
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();
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();
750 Handle(TDataStd_IntegerArray) aSAR;
751 if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) {
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
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) )
764 TDF_Label aFLab = ResultLabel().FindChild(aLab.Tag() + aNE);
765 if(!aFLab.FindAttribute(TDataStd_Integer::GetID(), anAtt))
766 aSAR->SetValue(1, 0);
770 aLabelFDS = ResultLabel().FindChild(aSAR->Value(1)); // !=0 -already exist
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);
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);
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
799 Handle(TDF_TagSource) aTS;
800 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
802 aTS->Set(aLabelFDS.Tag());
806 TDataStd_Integer::Set(aLabelFDS, aNum); //keep number of faces
808 Load1nFaces(MS, ShapeIn);
809 Load1nFaces(MS, Tool);
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);
820 // gp_Vec v1 = aVec1.Crossed(aVec2);
821 // cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
823 if((aVec1.Crossed(aVec2)).XYZ().Z() >= 0) isPositive = Standard_True;
825 isPositive = Standard_False;
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)
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));
839 theArI.SetValue(1, 1);
840 theArI.SetValue(2, 2);
842 theArI.SetValue(1, 2); //change order
843 theArI.SetValue(2, 1);
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)
852 Standard_Integer i, j, i1,i2, i3;
854 Standard_Boolean adjacent = Standard_False;
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;}
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;}
867 Standard_Integer aSum = i+j;
870 i1 = 3;i2 = 1;i3 = 2;
873 i1 = 2; i2 = 1;i3 = 3;
876 i1 = 1; i2 = 2;i3 = 3;
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
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
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
902 Standard_Integer aN = i3; i3 = i2;
907 theArI.SetValue(1, i1);
908 theArI.SetValue(2, i2);
909 theArI.SetValue(3, i3);
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)
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;
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;
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;}
936 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV12;}
938 aDjacent = Standard_True;
939 Standard_Integer aSum = i+j;
957 // i1,i2 - first pair of adjacent: aV1.
958 // i3,i4 - next pair of adjacent: aV2.
959 // find agjacent V (i3-i4)
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;
966 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i3)));
967 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV2 = aV12;
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;
984 // pair of adjacent i1-i2 is the nearest
987 // 3. sort inside pairs
988 if(!IsDirectionPositive(theAx, aCP1, theArP.Value(i1))) {//first must be positive direction
990 Standard_Integer aN = i2; i2 = i1;
994 if(!IsDirectionPositive(theAx, aCP2, theArP.Value(i3))) {//first must be positive direction
997 cout << "SortEdges4: i3 = "<<i3<< "i4 = "<< i4 << endl;
999 Standard_Integer aN = i4; i4 = i3;
1003 // 4. final order i1, i2, i3, i4 - Ok
1005 cout << "SortEdges4: i1 = " <<i1<<" i2 = "<<i2<< " i3 = "<<i3<< "i4 = "<< i4 << endl;
1007 theArI.SetValue(1, i1);
1008 theArI.SetValue(2, i2);
1009 theArI.SetValue(3, i3);
1010 theArI.SetValue(4, i4);
1012 // ======================================================================
1013 static void SortEdges5 (const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP,
1014 const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI)
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;
1025 TopoDS_Shape aV1, aV2, aV;
1026 Standard_Integer I=0, J1=0, J2=0;
1028 Standard_Boolean found = Standard_False;
1029 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
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;
1041 found = Standard_False;
1042 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
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)) {
1050 if(I != i) cout << "WARNING:: I != i, I = " << I << ", i = " << i <<endl;
1052 found = Standard_True;
1059 // aV1, aV2 - vetexes of middle Edge, I - index of middle Edge, J1, J2 = indexes of
1060 // adjacent edges of the middle edge
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;
1070 // find agjacent V (i4-i5)
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;
1077 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4)));
1078 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV3 = aV12;
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
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
1098 // goup of 2 edges i1-i2 is the nearest
1100 // 3.1. sort inside group of 2 edges
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;
1116 // 3.2. sort inside group of 3 edges
1119 aDP = theArP.Value(i4); //center of middle edge
1120 aCP = theArP.Value(i3);
1123 aDP = theArP.Value(i2);
1124 aCP = theArP.Value(i1);
1127 if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction
1128 Standard_Integer aN;
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);
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());
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());
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());
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
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;
1189 i1 = 3; i2 = 1; i3 = 2;
1192 i1 = 2; i2 = 1; i3 = 3;
1195 i1 = 1; i2 = 2; i3 = 3;
1198 i1 = 1; i2 = 2; i3 = 3;
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;}
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;}
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());
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());
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;
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;
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;}
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;}
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;}
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;}
1303 //=======================================================================
1304 // SortEdges: returns
1305 //=======================================================================
1306 static void SortEdges(const TopTools_ListOfShape& theListE, const gp_Ax1& theAx,
1307 TopTools_Array1OfShape& theARS)
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++) {
1317 for (i=1;It.More (); It.Next (),i++) {
1318 ArS.SetValue(i, It.Value ());
1320 ArP.SetValue(i, GetCenterPoint(It.Value()));
1324 // Identify position
1325 SortEdges2(ArP, theAx, ArI);
1328 SortEdges3(ArS, ArP, theAx, ArI);
1331 SortEdges4(ArS, ArP, theAx, ArI);
1334 SortEdges5(ArS, ArP, theAx, ArI);
1338 for(i=1;i<=ArI.Upper();i++) {
1340 cout << "SortEdges: i = " <<i<<" ArI.Value(i) = " <<ArI.Value(i)<< endl;
1342 theARS.SetValue(i, ArS.Value(ArI.Value(i)));
1346 //=======================================================================
1347 //function : LoadSymmetricalEdges
1349 //=======================================================================
1351 void QANewBRepNaming_BooleanOperationFeat::LoadSymmetricalEdges (BRepAlgoAPI_BooleanOperation& MS) const
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)
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;
1377 // ModDbgTools_Write(aShape, "S0");
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
1386 if(IsValidSurfType(TopoDS::Face(ObjSh)))
1387 aList.Append(aShape);
1389 if(aList1.Extent() == 0 )
1390 aList1.Assign(aList);
1392 aList2.Assign(aList);
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;
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();
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();
1417 if (aNF2 == 2) //second ent. has 2 valid faces
1418 FindAdjacent2(aList2, aListE2);
1420 FindAdjacent3(aList2, aListE2);
1422 FindAdjacent4(aList2, aListE2);
1424 aNE2 = aListE2.Extent();
1426 //aListE1, aListE2 - contains Edges
1427 // if(aNE1 < 2) return;
1428 // check topological compatibility
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
1436 TDF_Label aLabelEDS;
1437 if(aSAR->Value(2)) aLabelEDS = ResultLabel().FindChild(aSAR->Value(2)); // !=0
1439 // initial creation of EDS structure
1440 aLabelEDS = NewShapes();
1441 aSAR->SetValue(2, aLabelEDS.Tag()); //keep tag
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
1462 Handle(TDF_TagSource) aTS;
1463 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
1465 aTS->Set(aLabelEDS.Tag());
1466 anAtt->Set(aNE1+aNE2);
1470 TDataStd_Integer::Set(aLabelEDS, aNE1+aNE2); //keep number of edges
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.
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);
1486 TNaming_Builder aBuilder(aLab);
1487 aBuilder.Generated(aShape);
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);
1495 gp_Pnt aPnt1 = GetCenterPoint(aListE1.First());
1496 // gp_Pnt aPnt2 = GetCenterPoint(aListE2.First());
1497 if(IsDirectionPositive(anAx, anAx.Location(), aPnt1)) {
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);
1504 TNaming_Builder aBuilder(aLab);
1505 aBuilder.Generated(aShape);
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);
1513 TNaming_Builder aBuilder(aLab);
1514 aBuilder.Generated(aShape);
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);
1524 TNaming_Builder aBuilder(aLab);
1525 aBuilder.Generated(aShape);
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);
1533 TNaming_Builder aBuilder(aLab);
1534 aBuilder.Generated(aShape);
1540 //=======================================================================
1541 //function : ISWRCase2
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;
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;
1568 return Standard_False;
1571 //=======================================================================
1572 //function : LoadWRCase
1574 //=======================================================================
1576 void QANewBRepNaming_BooleanOperationFeat::LoadWRCase(BRepAlgoAPI_BooleanOperation& MS) const {
1577 const TopoDS_Shape& Result = MS.Shape();
1578 const TopAbs_ShapeEnum& ResType = ShapeType(Result);
1579 if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return;
1580 TopTools_ListOfShape aList;
1582 TopExp_Explorer anExp(Result, TopAbs_FACE);
1583 for(;anExp.More();anExp.Next()) {
1584 if(IsValidSurfType(TopoDS::Face(anExp.Current()))) {
1585 TopExp_Explorer anExp1(Result, TopAbs_FACE);
1586 for(;anExp1.More();anExp1.Next()) {
1587 if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) {
1588 TopTools_ListOfShape aList;
1589 aList.Append(anExp.Current());
1590 aList.Append(anExp1.Current());
1591 TopTools_ListOfShape anEList;
1592 FindAdjacent2(aList, anEList);
1593 if(anEList.Extent() == 2) {
1595 TopTools_ListIteratorOfListOfShape anEIt(anEList);
1596 GProp_GProps anE1Props, anE2Props;
1597 BRepGProp::LinearProperties(anEList.First(), anE1Props);
1598 BRepGProp::LinearProperties(anEList.Last(), anE2Props);
1600 const TDF_Label& WRE1Label = ResultLabel().NewChild();
1601 const TDF_Label& WRE2Label = ResultLabel().NewChild();
1602 const TDF_Label& WRV1Label = ResultLabel().NewChild();
1603 const TDF_Label& WRV2Label = ResultLabel().NewChild();
1605 TDataStd_Name::Set(WRE1Label, "WorkAroundEdge1");
1606 TDataStd_Name::Set(WRE2Label, "WorkAroundEdge2");
1607 TDataStd_Name::Set(WRV1Label, "WorkAroundVertex1");
1608 TDataStd_Name::Set(WRV2Label, "WorkAroundVertex2");
1611 TNaming_Builder anEBuilder1(WRE1Label);
1612 TNaming_Builder anEBuilder2(WRE2Label);
1613 TNaming_Builder aVBuilder1(WRV1Label);
1614 TNaming_Builder aVBuilder2(WRV2Label);
1616 if(anE1Props.Mass() > anE2Props.Mass()) {
1617 anEBuilder1.Generated(anEList.Last());
1618 anEBuilder2.Generated(anEList.First());
1619 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.Last())));
1620 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.Last())));
1622 anEBuilder1.Generated(anEList.First());
1623 anEBuilder2.Generated(anEList.Last());
1624 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.First())));
1625 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.First())));