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);
80 //=======================================================================
81 //function : QANewBRepNaming_BooleanOperationFeat
83 //=======================================================================
85 QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat() {}
87 //=======================================================================
88 //function : QANewBRepNaming_BooleanOperationFeat
90 //=======================================================================
92 QANewBRepNaming_BooleanOperationFeat::QANewBRepNaming_BooleanOperationFeat(const TDF_Label& ResultLabel):QANewBRepNaming_TopNaming(ResultLabel) {}
94 //=======================================================================
97 //=======================================================================
99 void QANewBRepNaming_BooleanOperationFeat::Init(const TDF_Label& ResultLabel) {
100 if(ResultLabel.IsNull())
101 Standard_NullObject::Raise("QANewBRepNaming_BooleanOperationFeat::Init The Result label is Null ...");
102 myResultLabel = ResultLabel;
105 //=======================================================================
106 //function : ModifiedFaces
108 //=======================================================================
110 TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedFaces() const {
112 const TDF_Label& ModifiedFacesLabel = ResultLabel().NewChild();
113 TDataStd_Name::Set(ModifiedFacesLabel, "ModifiedFaces");
114 return ModifiedFacesLabel;
116 return ResultLabel().NewChild();
120 //=======================================================================
121 //function : ModifiedEdges
123 //=======================================================================
125 TDF_Label QANewBRepNaming_BooleanOperationFeat::ModifiedEdges() const {
127 const TDF_Label& ModifiedEdgesLabel = ResultLabel().NewChild();
128 TDataStd_Name::Set(ModifiedEdgesLabel, "ModifiedEdges");
129 return ModifiedEdgesLabel;
131 return ResultLabel().NewChild();
135 //=======================================================================
136 //function : DeletedFaces
138 //=======================================================================
140 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedFaces() const {
142 const TDF_Label& DeletedFacesLabel = ResultLabel().NewChild();
143 TDataStd_Name::Set(DeletedFacesLabel, "DeletedFaces");
144 return DeletedFacesLabel;
146 return ResultLabel().NewChild();
150 //=======================================================================
151 //function : DeletedEdges
153 //=======================================================================
155 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedEdges() const {
157 const TDF_Label& DeletedEdgesLabel = ResultLabel().NewChild();
158 TDataStd_Name::Set(DeletedEdgesLabel, "DeletedEdges");
159 return DeletedEdgesLabel;
161 return ResultLabel().NewChild();
165 //=======================================================================
166 //function : DeletedVertices
168 //=======================================================================
170 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedVertices() const {
172 const TDF_Label& DeletedVerticesLabel = ResultLabel().NewChild();
173 TDataStd_Name::Set(DeletedVerticesLabel, "DeletedVertices");
174 return DeletedVerticesLabel;
176 return ResultLabel().NewChild();
180 //=======================================================================
181 //function : NewShapes
183 //=======================================================================
185 TDF_Label QANewBRepNaming_BooleanOperationFeat::NewShapes() const {
187 const TDF_Label& NewShapesLabel = ResultLabel().NewChild();
188 TDataStd_Name::Set(NewShapesLabel, "NewShapes");
189 return NewShapesLabel;
191 return ResultLabel().NewChild();
195 //=======================================================================
198 //=======================================================================
200 TDF_Label QANewBRepNaming_BooleanOperationFeat::Content() const {
202 const TDF_Label& ContentLabel = ResultLabel().NewChild();
203 TDataStd_Name::Set(ContentLabel, "Content");
206 return ResultLabel().NewChild();
210 //=======================================================================
211 //function : DeletedDegeneratedEdges
213 //=======================================================================
215 TDF_Label QANewBRepNaming_BooleanOperationFeat::DeletedDegeneratedEdges() const {
217 const TDF_Label& DegeneratedLabel = ResultLabel().NewChild();
218 TDataStd_Name::Set(DegeneratedLabel, "DeletedDegeneratedEdges");
219 return DegeneratedLabel;
221 return ResultLabel().NewChild();
225 //=======================================================================
226 //function : ShapeType
228 //=======================================================================
230 TopAbs_ShapeEnum QANewBRepNaming_BooleanOperationFeat::ShapeType(const TopoDS_Shape& theShape) {
231 TopAbs_ShapeEnum TypeSh = theShape.ShapeType();
232 if (TypeSh == TopAbs_COMPOUND || TypeSh == TopAbs_COMPSOLID) {
233 TopoDS_Iterator itr(theShape);
234 if (!itr.More()) return TypeSh;
235 TypeSh = ShapeType(itr.Value());
236 if(TypeSh == TopAbs_COMPOUND) return TypeSh;
238 for(; itr.More(); itr.Next())
239 if(ShapeType(itr.Value()) != TypeSh) return TopAbs_COMPOUND;
244 //=======================================================================
245 //function : GetShape
247 //=======================================================================
249 TopoDS_Shape QANewBRepNaming_BooleanOperationFeat::GetShape(const TopoDS_Shape& theShape) const {
250 if (theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID) {
251 TopoDS_Iterator itr(theShape);
252 if (itr.More()) return itr.Value();
257 //=======================================================================
258 //function : LoadWire
260 //=======================================================================
262 void QANewBRepNaming_BooleanOperationFeat::LoadWire(BRepAlgoAPI_BooleanOperation& MS) const {
263 // Naming of modified edges:
264 TNaming_Builder ModBuilder(ModifiedEdges());
265 QANewBRepNaming_Loader::LoadModifiedShapes (MS, MS.Shape1(), TopAbs_EDGE, ModBuilder);
267 // load generated vertexes
268 if(MS.HasGenerated()) {
269 TNaming_Builder nBuilder (NewShapes());
270 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_EDGE, nBuilder);
271 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder);
273 // Naming of deleted edges, dangle vertices
275 TNaming_Builder DelEBuilder(DeletedEdges());
276 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder);
277 TNaming_Builder DelVBuilder(DeletedVertices());
278 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_VERTEX, DelEBuilder);
282 //=======================================================================
283 //function : LoadShell
285 //=======================================================================
287 void QANewBRepNaming_BooleanOperationFeat::LoadShell(BRepAlgoAPI_BooleanOperation& MS) const {
288 // Naming of modified faces and dangle edges
289 TNaming_Builder ModFBuilder(ModifiedFaces());
290 QANewBRepNaming_Loader::LoadModifiedShapes(MS, MS.Shape1(), TopAbs_FACE, ModFBuilder);
291 TNaming_Builder ModEBuilder(ModifiedEdges());
292 QANewBRepNaming_Loader::LoadModifiedShapes(MS, MS.Shape1(), TopAbs_EDGE, ModEBuilder);
294 if(MS.HasGenerated()) {
295 TNaming_Builder nBuilder (NewShapes());
297 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape2(), TopAbs_FACE, nBuilder);
298 QANewBRepNaming_Loader::LoadGeneratedShapes (MS, MS.Shape1(), TopAbs_FACE, nBuilder);
300 // Naming of deleted faces edges:
302 TNaming_Builder DelFBuilder(DeletedFaces());
303 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_FACE, DelFBuilder);
305 TNaming_Builder DelEBuilder(DeletedEdges());
306 QANewBRepNaming_Loader::LoadDeletedShapes(MS, MS.Shape1(), TopAbs_EDGE, DelEBuilder);
310 //=======================================================================
311 //function : LoadContent
313 //=======================================================================
315 void QANewBRepNaming_BooleanOperationFeat::LoadContent(BRepAlgoAPI_BooleanOperation& MS) const {
316 if (MS.Shape().ShapeType() == TopAbs_COMPSOLID || MS.Shape().ShapeType() == TopAbs_COMPOUND) {
317 TopoDS_Iterator itr(MS.Shape());
318 Standard_Integer nbShapes = 0;
324 for (itr.Initialize(MS.Shape()); itr.More(); itr.Next()) {
325 TNaming_Builder bContent(Content());
326 bContent.Generated(itr.Value());
332 //=======================================================================
333 //function : LoadResult
335 //=======================================================================
337 void QANewBRepNaming_BooleanOperationFeat::LoadResult(BRepAlgoAPI_BooleanOperation& MS) const {
338 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
339 if (Tagger.IsNull()) return;
341 TNaming_Builder Builder (ResultLabel());
342 TopoDS_Shape aResult = MS.Shape();
343 if (aResult.ShapeType() == TopAbs_COMPOUND) {
344 Standard_Integer nbSubResults = 0;
345 TopoDS_Iterator itr(aResult);
346 for (; itr.More(); itr.Next()) nbSubResults++;
347 if (nbSubResults == 1) {
348 itr.Initialize(aResult);
349 if (itr.More()) aResult = itr.Value();
352 if (MS.Shape1().IsNull()) Builder.Generated(aResult);
353 else Builder.Modify(MS.Shape1(), aResult);
356 //=======================================================================
357 //function : LoadDegenerated
359 //=======================================================================
361 void QANewBRepNaming_BooleanOperationFeat::LoadDegenerated(BRepAlgoAPI_BooleanOperation& MS) const {
362 TopTools_IndexedMapOfShape allEdges;
363 TopExp::MapShapes(MS.Shape1(), TopAbs_EDGE, allEdges);
364 Standard_Integer i = 1;
365 for (; i <= allEdges.Extent(); i++) {
366 if (BRep_Tool::Degenerated(TopoDS::Edge(allEdges.FindKey(i)))) {
367 if (MS.IsDeleted(allEdges.FindKey(i))) {
368 TNaming_Builder DegeneratedBuilder(DeletedDegeneratedEdges());
369 DegeneratedBuilder.Generated(allEdges.FindKey(i));
371 TDataStd_Name::Set(DegeneratedBuilder.NamedShape()->Label(), "DeletedDegenerated");
378 //=======================================================================
379 //function : IsResultChanged
381 //=======================================================================
383 Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsResultChanged(BRepAlgoAPI_BooleanOperation& MS) const {
384 TopoDS_Shape ResSh = MS.Shape();
385 if (MS.Shape().ShapeType() == TopAbs_COMPOUND) {
386 Standard_Integer nbSubResults = 0;
387 TopoDS_Iterator itr(MS.Shape());
388 for (; itr.More(); itr.Next()) nbSubResults++;
389 if (nbSubResults == 1) {
390 itr.Initialize(MS.Shape());
391 if (itr.More()) ResSh = itr.Value();
394 return MS.Shape1().IsSame(ResSh);
396 //=======================================================================
397 // Workaround for evolution 1:n
398 //=======================================================================
399 static Standard_Boolean IsValidSurfType(const TopoDS_Face& theFace) {
400 BRepAdaptor_Surface anAdapt(theFace);
401 Handle( Adaptor3d_HCurve ) aBasisCurve;
402 const GeomAbs_SurfaceType& aType = anAdapt.GetType();
403 if(aType == GeomAbs_Cylinder || aType == GeomAbs_Cone)
404 return Standard_True;
405 else if(aType == GeomAbs_SurfaceOfRevolution){
406 aBasisCurve = anAdapt.BasisCurve();
407 if (aBasisCurve->GetType() == GeomAbs_Line)
408 return Standard_True;
410 else if(aType == GeomAbs_SurfaceOfExtrusion) {
411 aBasisCurve = anAdapt.BasisCurve();
412 if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse)
413 return Standard_True;
416 ModDbgTools_Write(theFace, "Surf");
418 return Standard_False;
420 //=======================================================================
421 //function : IsWRCase
423 //=======================================================================
425 Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsWRCase(const BRepAlgoAPI_BooleanOperation& MS) {
426 const TopoDS_Shape& ObjSh = MS.Shape1();
427 const TopoDS_Shape& ToolSh = MS.Shape2();
428 const TopAbs_ShapeEnum& Type1 = ShapeType(ObjSh);
429 if(Type1 == TopAbs_COMPOUND || Type1 > TopAbs_FACE) return Standard_False;
430 const TopAbs_ShapeEnum& Type2 = ShapeType(ToolSh);
431 if(Type2 == TopAbs_COMPOUND || Type2 > TopAbs_FACE) return Standard_False;
432 TopTools_ListOfShape aList;
435 if(Type1 != TopAbs_FACE) {
436 TopExp_Explorer anExp(ObjSh, TopAbs_FACE);
437 for(;anExp.More();anExp.Next()) {
438 if(IsValidSurfType(TopoDS::Face(anExp.Current())))
439 aList.Append(anExp.Current());
442 if(IsValidSurfType(TopoDS::Face(ObjSh)))
444 if(aList.Extent() == 1) {
445 if(Type2 != TopAbs_FACE) {
446 TopExp_Explorer anExp(ToolSh, TopAbs_FACE);
447 for(;anExp.More();anExp.Next()) {
448 if(IsValidSurfType(TopoDS::Face(anExp.Current())))
449 aList.Append(anExp.Current());
452 if(IsValidSurfType(TopoDS::Face(ToolSh)))
453 aList.Append(ToolSh);
454 if(aList.Extent() == 2) return Standard_True;
456 return Standard_False;
459 //=======================================================================
460 static gp_Ax1 ComputeAxis(const TopoDS_Shape& theShape) {
462 TopExp_Explorer anExp(theShape, TopAbs_FACE);
463 for(;anExp.More();anExp.Next()) {
464 aFace = TopoDS::Face(anExp.Current());
465 BRepAdaptor_Surface anAdapt(aFace);
466 Handle( Adaptor3d_HCurve ) aBasisCurve;
467 const GeomAbs_SurfaceType& aType = anAdapt.GetType();
468 if(aType == GeomAbs_Cylinder)
469 return anAdapt.Cylinder().Axis();
470 else if(aType == GeomAbs_Cone)
471 return anAdapt.Cone().Axis();
472 else if(aType == GeomAbs_SurfaceOfRevolution)
473 return anAdapt.AxeOfRevolution();
474 else if(aType == GeomAbs_SurfaceOfExtrusion) {
475 aBasisCurve = anAdapt.BasisCurve();
476 if (aBasisCurve->GetType() == GeomAbs_Circle)
477 return aBasisCurve->Circle().Axis();
478 else if(aBasisCurve->GetType() == GeomAbs_Ellipse)
479 return aBasisCurve->Ellipse().Axis();
484 //==============================================================================
486 //==========================================================================
487 static Standard_Integer Identify(const TopoDS_Face& theFace, const gp_Ax1& theAx) {
489 BRepGProp::SurfaceProperties(theFace, aGProp);
490 gp_Pnt aPoint = aGProp.CentreOfMass();
491 gp_Vec aV1(theAx.Direction());
492 gp_Vec aV2(theAx.Location(), aPoint);
494 gp_Vec v1 = aV1.Crossed(aV2);
495 cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
497 if((aV1.Crossed(aV2)).XYZ().Z() >= 0) return 1; //right orientation
498 return (-1); //left orientation
501 //=======================================================================
502 //function : LoadModified11
504 //=======================================================================
506 void QANewBRepNaming_BooleanOperationFeat::LoadModified11 (BRepAlgoAPI_BooleanOperation& MS,
507 const TopoDS_Shape& ShapeIn,
508 const TopAbs_ShapeEnum KindOfShape) const
511 TopTools_MapOfShape View;
512 Standard_Boolean found = Standard_False;
513 TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape);
514 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
515 const TopoDS_Shape& Root = ShapeExplorer.Current ();
516 if (!View.Add(Root)) continue;
517 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
518 if(Shapes.Extent() == 1) {found = Standard_True; break;}
523 ShapeExplorer.Init (ShapeIn, KindOfShape);
524 TNaming_Builder Builder(ModifiedFaces());
525 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
526 const TopoDS_Shape& Root = ShapeExplorer.Current ();
527 if (!View.Add(Root)) continue;
528 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
529 if(Shapes.Extent() > 1) continue;
530 TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
531 for (;ShapesIterator.More (); ShapesIterator.Next ()) {
532 const TopoDS_Shape& newShape = ShapesIterator.Value ();
533 if (!Root.IsSame (newShape)) {
534 //put shapes with evolution 1:1 (may be Compound)
536 TCollection_AsciiString entry;
537 TDF_Tool::Entry(Builder.NamedShape()->Label(), entry);
538 cout << "Add shape to Compound at Label = "<< entry <<endl;
540 Builder.Modify (Root,newShape);
546 //======================================================================
547 static gp_Pnt GetCenterPoint(const TopoDS_Shape& theEdge)
550 BRepGProp::LinearProperties(theEdge, aGProp);
551 return aGProp.CentreOfMass();
553 //===================================================================
554 static void SortRootFaces(TopTools_ListOfShape& theList, const TopoDS_Shape& theShape)
556 TopTools_ListOfShape aList;
557 Standard_Integer aNum = theList.Extent();
558 if(aNum <= 1) return;
559 gp_Ax1 anAx = ComputeAxis(theShape);
560 TopTools_Array1OfShape ArS(1, aNum);
561 TColgp_Array1OfPnt ArP(1, aNum);
562 TColStd_Array1OfInteger ArI(1, aNum);
563 TopTools_ListIteratorOfListOfShape It(theList);
565 for(i=1;It.More();It.Next(),i++) {
566 ArS.SetValue(i, It.Value ());
568 ArP.SetValue(i, GetCenterPoint(It.Value()));
571 gp_Pnt aPnt = anAx.Location();
572 Standard_Integer I, j;
573 for(j=1;j <= aNum; j++) {
574 if(ArI.Value(j) == -1) continue;
575 Standard_Real aD1 = aPnt.Distance(ArP(j));
577 for(i=1;i <= aNum; i++) {
579 if(ArI.Value(i) == -1) continue;
580 Standard_Real aD2 = aPnt.Distance(ArP(i));
586 if (I == 0) continue;
588 aList.Append(ArS.Value(I));
589 if(aList.Extent() == aNum -1) {
590 for(i=1; i<=aNum;i++)
591 if(ArI.Value(i) != -1) aList.Append(ArS.Value(i));
594 theList.Assign(aList);
596 //=======================================================================
597 static void Sort2Faces(const TopTools_ListOfShape& Shapes,
598 const gp_Ax1& theAx, TopTools_ListOfShape& theList)
601 TopTools_ListIteratorOfListOfShape It(Shapes);
602 for(;It.More();It.Next()) {
603 if(Identify(TopoDS::Face(It.Value()), theAx) == 1)
604 theList.Prepend(It.Value()); //Pos
605 else theList.Append(It.Value()); //Neg
609 //=======================================================================
610 static void Sort3Faces(const TopTools_ListOfShape& theListIn, TopTools_ListOfShape& theListOut)
612 TopTools_ListIteratorOfListOfShape It (theListIn);
613 TopTools_Array1OfShape ArS(1, theListIn.Extent());
614 TColgp_Array1OfPnt ArP(1, theListIn.Extent());
617 for(i=1;It.More();It.Next(),i++) {
618 ArS.SetValue(i, It.Value());
619 ArP.SetValue(i, GetCenterPoint(It.Value()));
622 Standard_Boolean found = Standard_False;
623 Standard_Integer j, i1, i2, i3;
626 TopExp_Explorer anExp1(ArS.Value(i), TopAbs_EDGE);
627 for(;anExp1.More();anExp1.Next()) {
630 TopExp_Explorer anExp2(ArS.Value(j), TopAbs_EDGE);
631 for(;anExp2.More();anExp2.Next()) {
632 if(anExp1.Current().IsSame(anExp2.Current())){
633 found = Standard_True;
634 anEdge = TopoDS::Edge(anExp1.Current());
657 //i1,i2 - two adjacent faces via sim-edge
658 gp_Pnt aPnt1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
659 gp_Pnt aPnt2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
660 gp_Vec aVec(aPnt1, aPnt2);
661 gp_Ax1 anAx(aPnt1, gp_Dir(aVec));
662 if (Identify(TopoDS::Face(ArS.Value(i1)), anAx) == -1) {//neg
663 i=i2; i2=i1; //i1 < = > i2
666 theListOut.Append(ArS.Value(i1));
667 theListOut.Append(ArS.Value(i2));
668 theListOut.Append(ArS.Value(i3)); //single
670 //=======================================================================
671 //function : Load1nFaces
673 //=======================================================================
675 void QANewBRepNaming_BooleanOperationFeat::Load1nFaces(BRepAlgoAPI_BooleanOperation& MS, const TopoDS_Shape& ShapeIn) const
678 TopTools_MapOfShape View;
679 TopTools_ListOfShape aListR;
680 TopExp_Explorer ShapeExplorer (ShapeIn, TopAbs_FACE);
681 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
682 const TopoDS_Shape& Root = ShapeExplorer.Current ();
683 if (!View.Add(Root)) continue;
684 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
685 if(Shapes.Extent() < 2) continue;
688 if(ShapeIn.IsEqual(MS.Shape1()))
689 if(aListR.Extent() > 1) SortRootFaces(aListR, ShapeIn);
691 TopTools_ListIteratorOfListOfShape Itr(aListR);
692 for(;Itr.More();Itr.Next()) {
693 const TopoDS_Shape& Root = Itr.Value();
694 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
695 TopTools_ListOfShape aList;
696 gp_Ax1 anAx = ComputeAxis(MS.Shape2());
697 if(Shapes.Extent() == 2)
698 Sort2Faces(Shapes, anAx, aList);
699 else if(Shapes.Extent() == 3)
700 Sort3Faces(Shapes, aList);
701 TopTools_ListIteratorOfListOfShape It(aList);
702 for(;It.More();It.Next()) {
703 TNaming_Builder aBuilder(NewShapes());
704 // aBuilder.Modify(Root,It.Value ());
705 aBuilder.Generated(It.Value ());
710 //=======================================================================
711 //function : LoadModified faces
712 //purpose : 1 : n modification
713 //=======================================================================
715 void QANewBRepNaming_BooleanOperationFeat::LoadModified1n (BRepAlgoAPI_BooleanOperation& MS,
716 const TopoDS_Shape& ShapeIn,
717 const TopAbs_ShapeEnum KindOfShape) const
720 //fill modification 1:n
721 TopTools_MapOfShape View;
722 Standard_Integer aNum = 0;
723 TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape);
724 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
725 const TopoDS_Shape& Root = ShapeExplorer.Current ();
726 if (!View.Add(Root)) continue;
727 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
728 if(Shapes.Extent() >= 2) aNum += Shapes.Extent();
732 const TopoDS_Shape& Tool = MS.Shape2();
733 ShapeExplorer.Init (Tool, KindOfShape);
734 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
735 const TopoDS_Shape& Root = ShapeExplorer.Current ();
736 if (!View.Add(Root)) continue;
737 const TopTools_ListOfShape& Shapes = MS.Modified (Root);
738 if(Shapes.Extent() >= 2) aNum += Shapes.Extent();
741 Handle(TDataStd_IntegerArray) aSAR;
742 if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) {
744 aSAR = TDataStd_IntegerArray::Set(ResultLabel(), 1, 2);
745 aSAR->SetValue(1, 0); //tag num for faces structure
746 aSAR->SetValue(2, 0); //tag num for edges structure
750 Standard_Integer aNE =0;
751 TDF_Label aLab = ResultLabel().FindChild(aSAR->Value(2));
752 Handle(TDataStd_Integer) anAtt;
753 if(aLab.FindAttribute(TDataStd_Integer::GetID(), anAtt) )
755 TDF_Label aFLab = ResultLabel().FindChild(aLab.Tag() + aNE);
756 if(!aFLab.FindAttribute(TDataStd_Integer::GetID(), anAtt))
757 aSAR->SetValue(1, 0);
761 aLabelFDS = ResultLabel().FindChild(aSAR->Value(1)); // !=0 -already exist
763 // initial creation of FDS structure
764 Handle(TDF_TagSource) aTS;
765 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
766 aLabelFDS = NewShapes();
767 // aLabelFDS = ResultLabel().FindChild(aSAR->Value(1));
768 aSAR->SetValue(1, aLabelFDS.Tag()); //keep tag
769 aTS->Set(aLabelFDS.Tag()-1);
771 Handle(TDataStd_Integer) anAtt;
772 if(aLabelFDS.FindAttribute(TDataStd_Integer::GetID(), anAtt) ) {
773 // modification : check compatibility
774 if(anAtt->Get() != aNum) {
775 cout << "WARNING: Case isn't mantained - Number of Faces was changed!"<<endl;
776 // mark all structure as Deleted
777 Standard_Integer aN = aLabelFDS.Tag()+anAtt->Get();
778 for(Standard_Integer i=aLabelFDS.Tag(); i < aN; i++) {
779 TDF_Label aLab = ResultLabel().FindChild(i, Standard_False);
781 Handle(TNaming_NamedShape) aNS;
782 if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
783 TopoDS_Shape aShape = aNS->Get();
784 TNaming_Builder aBuilder(aLab);
785 aBuilder.Delete(aShape); //Deleted
790 Handle(TDF_TagSource) aTS;
791 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
793 aTS->Set(aLabelFDS.Tag());
797 TDataStd_Integer::Set(aLabelFDS, aNum); //keep number of faces
799 Load1nFaces(MS, ShapeIn);
800 Load1nFaces(MS, Tool);
804 //======================================================================
805 static Standard_Boolean IsDirectionPositive (const gp_Ax1& theAx, const gp_Pnt thePnt1,
806 const gp_Pnt thePnt2) {
807 Standard_Boolean isPositive;
808 gp_Vec aVec1(theAx.Direction());
809 gp_Vec aVec2(thePnt1, thePnt2);
811 // gp_Vec v1 = aVec1.Crossed(aVec2);
812 // cout <<" Z of V1 = " << v1.XYZ().Z() << endl;
814 if((aVec1.Crossed(aVec2)).XYZ().Z() >= 0) isPositive = Standard_True;
816 isPositive = Standard_False;
819 //======================================================================
820 // i => ArS[i] : ArP[i] ; i = ArI[j]
821 //======================================================================
822 static void SortEdges2(const TColgp_Array1OfPnt& theArP, const gp_Ax1& theAx,
823 TColStd_Array1OfInteger& theArI)
825 gp_Pnt aPnt = theAx.Location();
826 //sort : the nearest point must be first
827 Standard_Real aD1 = aPnt.Distance(theArP.Value(1));
828 Standard_Real aD2 = aPnt.Distance(theArP.Value(2));
830 theArI.SetValue(1, 1);
831 theArI.SetValue(2, 2);
833 theArI.SetValue(1, 2); //change order
834 theArI.SetValue(2, 1);
837 //======================================================================
838 // i => ArS[i] : ArP[i] ; i = ArI[j]
839 //======================================================================
840 static void SortEdges3(const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP,
841 const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI)
843 Standard_Integer i, j, i1,i2, i3;
845 Standard_Boolean adjacent = Standard_False;
849 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
850 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j)));
851 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j)));
852 if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) {adjacent = Standard_True;aV = aV11;}
854 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
855 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {adjacent = Standard_True;aV = aV12;}
858 Standard_Integer aSum = i+j;
861 i1 = 3;i2 = 1;i3 = 2;
864 i1 = 2; i2 = 1;i3 = 3;
867 i1 = 1; i2 = 2;i3 = 3;
874 gp_Pnt aPnt = theAx.Location();
875 // i1 - index of single edge
876 Standard_Real aD1 = aPnt.Distance(theArP.Value(i1));
877 Standard_Real aD2 = aPnt.Distance(theArP.Value(i2));
878 if(aD1 > aD2) { //cyclic shift
879 Standard_Integer aN = i3;// i1 => i3 - to the end
881 // pair of adjacent i1, i2
882 gp_Pnt aCP = BRep_Tool::Pnt(TopoDS::Vertex(aV));
883 if(!IsDirectionPositive(theAx, aCP, theArP.Value(i1))) {//first must be positive direction
889 // pair of adjacent i2, i3
890 gp_Pnt aCP = BRep_Tool::Pnt(TopoDS::Vertex(aV));
891 if(!IsDirectionPositive(theAx, aCP, theArP.Value(i2))) {//first must be positive direction
893 Standard_Integer aN = i3; i3 = i2;
898 theArI.SetValue(1, i1);
899 theArI.SetValue(2, i2);
900 theArI.SetValue(3, i3);
903 //======================================================================
904 // i => ArS[i] : ArP[i] ; i = ArI[j]
905 //======================================================================
906 static void SortEdges4(const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP,
907 const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI)
909 // 1. find adjacent edges, build pairs in ArI
910 // 2. find nearest pair, reorganize ArI
911 // 3. sort inside pairs
912 // =======================================
913 Standard_Integer i, j, i1,i2, i3, i4;
917 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
918 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
919 Standard_Boolean aDjacent;
922 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j)));
923 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j)));
924 aDjacent = Standard_False;
925 if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV11;}
927 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {aDjacent = Standard_True;aV1 = aV12;}
929 aDjacent = Standard_True;
930 Standard_Integer aSum = i+j;
948 // i1,i2 - first pair of adjacent: aV1.
949 // i3,i4 - next pair of adjacent: aV2.
950 // find agjacent V (i3-i4)
952 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i3)));
953 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i4)));
954 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4)));
955 if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) aV2 = aV11;
957 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i3)));
958 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV2 = aV12;
961 // 2. find nearest pair
962 gp_Pnt aCP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1));
963 gp_Pnt aCP2 = BRep_Tool::Pnt(TopoDS::Vertex(aV2));
964 gp_Pnt aPnt = theAx.Location();
965 Standard_Real aD1 = aPnt.Distance(aCP1);//i1-i2
966 Standard_Real aD2 = aPnt.Distance(aCP2);//i3-i4
967 if(aD1 > aD2) { //change order of pairs
968 Standard_Integer a3 = i3;// i1,i2 => i3,i4 - to the end
969 Standard_Integer a4 = i4;
975 // pair of adjacent i1-i2 is the nearest
978 // 3. sort inside pairs
979 if(!IsDirectionPositive(theAx, aCP1, theArP.Value(i1))) {//first must be positive direction
981 Standard_Integer aN = i2; i2 = i1;
985 if(!IsDirectionPositive(theAx, aCP2, theArP.Value(i3))) {//first must be positive direction
988 cout << "SortEdges4: i3 = "<<i3<< "i4 = "<< i4 << endl;
990 Standard_Integer aN = i4; i4 = i3;
994 // 4. final order i1, i2, i3, i4 - Ok
996 cout << "SortEdges4: i1 = " <<i1<<" i2 = "<<i2<< " i3 = "<<i3<< "i4 = "<< i4 << endl;
998 theArI.SetValue(1, i1);
999 theArI.SetValue(2, i2);
1000 theArI.SetValue(3, i3);
1001 theArI.SetValue(4, i4);
1003 // ======================================================================
1004 static void SortEdges5 (const TopTools_Array1OfShape& theArS, const TColgp_Array1OfPnt& theArP,
1005 const gp_Ax1& theAx, TColStd_Array1OfInteger& theArI)
1007 // =======================================
1008 // 1. find middle edge from gr. of 3 edges, build two groups in ArI
1009 // 2. find nearest group, reorganize ArI - nerest => top
1010 // 3. sort inside groups
1011 // 3.1. sort inside group of 2 edges
1012 // 3.2. sort inside group of 3 edges
1013 // =======================================
1014 Standard_Integer i, j, i1,i2, i3, i4, i5;
1016 TopoDS_Shape aV1, aV2, aV;
1017 Standard_Integer I=0, J1=0, J2=0;
1019 Standard_Boolean found = Standard_False;
1020 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i)));
1023 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j)));
1024 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j)));
1025 if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) {
1026 aV1 = aV11; I = i; J1 = j;
1027 found = Standard_True;
1032 found = Standard_False;
1033 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i)));
1036 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(j)));
1037 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(j)));
1038 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) {
1041 if(I != i) cout << "WARNING:: I != i, I = " << I << ", i = " << i <<endl;
1043 found = Standard_True;
1050 // aV1, aV2 - vetexes of middle Edge, I - index of middle Edge, J1, J2 = indexes of
1051 // adjacent edges of the middle edge
1053 // init & shift group from 3 edges on the top
1054 i1=J1; i2=I; i3 = J2; i4=0; i5=0;
1055 for(i=1; i<=5;i++) {
1056 if(i==i1 || i==i2 ||i==i3) continue;
1061 // find agjacent V (i4-i5)
1063 const TopoDS_Shape& aV11 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i4)));
1064 const TopoDS_Shape& aV21 = TopExp::FirstVertex(TopoDS::Edge(theArS.Value(i5)));
1065 const TopoDS_Shape& aV22 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i5)));
1066 if(aV11.IsSame(aV21) || aV11.IsSame(aV22)) aV3 = aV11;
1068 const TopoDS_Shape& aV12 = TopExp::LastVertex(TopoDS::Edge(theArS.Value(i4)));
1069 if(aV12.IsSame(aV21) || aV12.IsSame(aV22)) aV3 = aV12;
1072 // 2. find nearest group (aV1, aV3), reorganize ArI - nerest => top
1073 gp_Pnt aDP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1));
1074 gp_Pnt aDP2 = BRep_Tool::Pnt(TopoDS::Vertex(aV2));
1075 gp_Pnt aDP3 = BRep_Tool::Pnt(TopoDS::Vertex(aV3));
1076 gp_Pnt aPnt = theAx.Location();
1077 Standard_Real aD1 = aPnt.Distance(aDP1);//i1-i2-i3
1078 Standard_Real aD2 = aPnt.Distance(aDP3);//i4-i5
1079 Standard_Integer aTop = 3;
1080 if(aD1 > aD2) { //change order of groups
1082 Standard_Integer a4 = i4;// i1,i2 => i4,i5 - to the end
1083 Standard_Integer a5 = i5;
1084 i4 = i2; i5 = i1; // i4 - middle edge
1089 // goup of 2 edges i1-i2 is the nearest
1091 // 3.1. sort inside group of 2 edges
1093 if(aTop == 2) {aDP = aDP1; aCP = theArP.Value(i1);} //i1,i2
1094 else {aDP = aDP3; aCP = theArP.Value(i4);} //i4, i5 - group of 2 edges at the bottom
1095 if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction
1096 Standard_Integer aN;
1107 // 3.2. sort inside group of 3 edges
1110 aDP = theArP.Value(i4); //center of middle edge
1111 aCP = theArP.Value(i3);
1114 aDP = theArP.Value(i2);
1115 aCP = theArP.Value(i1);
1118 if(!IsDirectionPositive(theAx, aDP, aCP)) {//first must be positive direction
1119 Standard_Integer aN;
1130 // 4. final order i1, i2, i3, i4, i5 - Ok
1131 theArI.SetValue(1, i1);
1132 theArI.SetValue(2, i2);
1133 theArI.SetValue(3, i3);
1134 theArI.SetValue(4, i4);
1135 theArI.SetValue(5, i5);
1137 //=======================================================================
1138 static void FindAdjacent2(const TopTools_ListOfShape& theList,
1139 TopTools_ListOfShape& theListOfEdges) {
1140 TopTools_ListIteratorOfListOfShape It (theList);
1141 const TopoDS_Shape& aShape1 = It.Value (); It.Next ();
1142 const TopoDS_Shape& aShape2 = It.Value ();
1143 if(!aShape1.IsNull() && !aShape2.IsNull()) {
1144 TopExp_Explorer anExp1(aShape1, TopAbs_EDGE);
1145 for(;anExp1.More();anExp1.Next()) {
1146 TopExp_Explorer anExp2(aShape2, TopAbs_EDGE);
1147 for(;anExp2.More();anExp2.Next()) {
1148 if(anExp1.Current().IsSame(anExp2.Current()))
1149 theListOfEdges.Append(anExp1.Current());
1154 //=======================================================================
1155 static void FindAdjacent3(const TopTools_ListOfShape& theList,
1156 TopTools_ListOfShape& theListOfEdges) {
1157 TopTools_ListIteratorOfListOfShape It (theList);
1158 TopTools_Array1OfShape ArS(1, theList.Extent());
1159 TColgp_Array1OfPnt ArP(1, theList.Extent());
1160 TColgp_Array1OfDir ArD(1, theList.Extent());
1162 for(i=1;It.More();It.Next(),i++) {
1163 ArS.SetValue(i, It.Value());
1164 gp_Ax1 anAx = ComputeAxis(It.Value());
1165 ArP.SetValue(i, anAx.Location());
1166 ArD.SetValue(i, anAx.Direction());
1168 Standard_Boolean aDjacent = Standard_False;
1169 Standard_Integer j, i2, i3; //i2, i3 - indexes of two adjacent faces having the same surface
1170 Standard_Integer i1 = 0; //single face
1174 if(ArP.Value(i).IsEqual(ArP.Value(j), Precision::Confusion())
1175 && ArD.Value(i).IsEqual(ArD.Value(j), Precision::Angular())) {
1176 aDjacent = Standard_True;
1177 Standard_Integer aSum = i+j;
1180 i1 = 3; i2 = 1; i3 = 2;
1183 i1 = 2; i2 = 1; i3 = 3;
1186 i1 = 1; i2 = 2; i3 = 3;
1189 i1 = 1; i2 = 2; i3 = 3;
1197 TopExp_Explorer anExp1(ArS.Value(i1), TopAbs_EDGE);
1198 for(;anExp1.More();anExp1.Next()) {
1199 Standard_Boolean found = Standard_False;
1200 TopExp_Explorer anExp2(ArS.Value(i2), TopAbs_EDGE);
1201 for(;anExp2.More();anExp2.Next()) {
1202 if(anExp1.Current().IsSame(anExp2.Current()))
1203 {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;}
1206 TopExp_Explorer anExp3(ArS.Value(i3), TopAbs_EDGE);
1207 for(;anExp3.More();anExp3.Next()) {
1208 if(anExp1.Current().IsSame(anExp3.Current()))
1209 {theListOfEdges.Append(anExp1.Current());break;}
1214 //=======================================================================
1215 static void FindAdjacent4(const TopTools_ListOfShape& theList,
1216 TopTools_ListOfShape& theListOfEdges) {
1217 TopTools_ListIteratorOfListOfShape It (theList);
1218 TopTools_Array1OfShape ArS(1, theList.Extent());
1219 TColgp_Array1OfPnt ArP(1, theList.Extent());
1220 TColgp_Array1OfDir ArD(1, theList.Extent());
1222 for(i=1;It.More();It.Next(),i++) {
1223 ArS.SetValue(i, It.Value());
1224 gp_Ax1 anAx = ComputeAxis(It.Value());
1225 ArP.SetValue(i, anAx.Location());
1226 ArD.SetValue(i, anAx.Direction());
1229 Standard_Integer j, i3=0, i4 = 0;//i3, i4 - indexes of two adjacent faces having the same surface
1230 Standard_Integer i1 = 0, i2 = 0;
1231 Standard_Boolean aDjacent = Standard_False;
1235 if(ArP.Value(i).IsEqual(ArP.Value(j), Precision::Confusion())
1236 && ArD.Value(i).IsEqual(ArD.Value(j), Precision::Angular())) {
1237 aDjacent = Standard_True;
1238 Standard_Integer aSum = i+j;
1259 TopExp_Explorer anExp1(ArS.Value(i1), TopAbs_EDGE);
1260 for(;anExp1.More();anExp1.Next()) {
1261 Standard_Boolean found = Standard_False;
1262 TopExp_Explorer anExp2(ArS.Value(i3), TopAbs_EDGE);
1263 for(;anExp2.More();anExp2.Next()) {
1264 if(anExp1.Current().IsSame(anExp2.Current()))
1265 {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;}
1268 TopExp_Explorer anExp3(ArS.Value(i4), TopAbs_EDGE);
1269 for(;anExp3.More();anExp3.Next()) {
1270 if(anExp1.Current().IsSame(anExp3.Current()))
1271 {theListOfEdges.Append(anExp1.Current());break;}
1276 anExp1.Init(ArS.Value(i2), TopAbs_EDGE);
1277 for(;anExp1.More();anExp1.Next()) {
1278 Standard_Boolean found = Standard_False;
1279 TopExp_Explorer anExp2(ArS.Value(i3), TopAbs_EDGE);
1280 for(;anExp2.More();anExp2.Next()) {
1281 if(anExp1.Current().IsSame(anExp2.Current()))
1282 {theListOfEdges.Append(anExp1.Current()); found=Standard_True; break;}
1285 TopExp_Explorer anExp3(ArS.Value(i4), TopAbs_EDGE);
1286 for(;anExp3.More();anExp3.Next()) {
1287 if(anExp1.Current().IsSame(anExp3.Current()))
1288 {theListOfEdges.Append(anExp1.Current());break;}
1294 //=======================================================================
1295 // SortEdges: returns
1296 //=======================================================================
1297 static void SortEdges(const TopTools_ListOfShape& theListE, const gp_Ax1& theAx,
1298 TopTools_Array1OfShape& theARS)
1301 Standard_Integer aNE1 = theListE.Extent();
1302 TopTools_Array1OfShape ArS(1, aNE1);
1303 TColgp_Array1OfPnt ArP(1, aNE1);
1304 TColStd_Array1OfInteger ArI(1, aNE1);
1305 TopTools_ListIteratorOfListOfShape It (theListE);//pairs of edges
1306 //for (Standard_Integer i=1;It.More (); It.Next (),i++) {
1308 for (i=1;It.More (); It.Next (),i++) {
1309 ArS.SetValue(i, It.Value ());
1311 ArP.SetValue(i, GetCenterPoint(It.Value()));
1315 // Identify position
1316 SortEdges2(ArP, theAx, ArI);
1319 SortEdges3(ArS, ArP, theAx, ArI);
1322 SortEdges4(ArS, ArP, theAx, ArI);
1325 SortEdges5(ArS, ArP, theAx, ArI);
1329 for(i=1;i<=ArI.Upper();i++) {
1331 cout << "SortEdges: i = " <<i<<" ArI.Value(i) = " <<ArI.Value(i)<< endl;
1333 theARS.SetValue(i, ArS.Value(ArI.Value(i)));
1337 //=======================================================================
1338 //function : LoadSymmetricalEdges
1340 //=======================================================================
1342 void QANewBRepNaming_BooleanOperationFeat::LoadSymmetricalEdges (BRepAlgoAPI_BooleanOperation& MS) const
1344 const TopoDS_Shape& aResult = MS.Shape();
1345 if(aResult.IsNull()) return;
1346 const TopoDS_Shape& ObjSh = MS.Shape1();
1347 const TopoDS_Shape& ToolSh = MS.Shape2();
1348 const TopAbs_ShapeEnum& Type1 = ShapeType(ObjSh);
1349 if(Type1 == TopAbs_COMPOUND || Type1 > TopAbs_FACE) return;
1350 const TopAbs_ShapeEnum& Type2 = ShapeType(ToolSh);
1351 if(Type2 == TopAbs_COMPOUND || Type2 > TopAbs_FACE) return;
1352 TopTools_ListOfShape aList0;
1353 if (aResult.ShapeType() == TopAbs_COMPOUND) {
1354 TopoDS_Iterator itr(aResult);
1355 for (; itr.More(); itr.Next())
1356 aList0.Append(itr.Value()); //collect separated entities (bodies)
1359 if(aList0.Extent() > 2) return; // case > 2 ent. is not considered
1360 TopTools_ListOfShape aList1, aList2;
1361 TopTools_ListIteratorOfListOfShape It (aList0); //each item (body) must have at least 1 pair
1362 // of "cyl/con" surfaces (in some cases may be 3 or 4 faces depending on sim-edge position)
1363 for (;It.More (); It.Next ()) {
1364 const TopoDS_Shape& aShape = It.Value (); //1-st solid/shell
1365 TopTools_ListOfShape aList;
1368 // ModDbgTools_Write(aShape, "S0");
1370 if(aShape.ShapeType() != TopAbs_FACE) {
1371 TopExp_Explorer anExp(aShape, TopAbs_FACE);
1372 for(;anExp.More();anExp.Next()) {
1373 if(IsValidSurfType(TopoDS::Face(anExp.Current())))
1374 aList.Append(anExp.Current()); // faces of the current entity
1377 if(IsValidSurfType(TopoDS::Face(ObjSh)))
1378 aList.Append(aShape);
1380 if(aList1.Extent() == 0 )
1381 aList1.Assign(aList);
1383 aList2.Assign(aList);
1385 // aList1,2 contain pairs of faces having more then 1 neghbour edge (each pair)
1386 const Standard_Integer aNF1 = aList1.Extent(); // keep n of faces of the first entity
1387 const Standard_Integer aNF2 = aList2.Extent(); // keep n of faces of the second entity
1388 if(aNF1 + aNF2 < 2) return;
1391 TopTools_ListOfShape aListE1, aListE2;
1392 Standard_Integer aNE1=0,aNE2=0;
1393 if(aNF1 == 2 && !aNF2) {//trivial case - only 2 faces
1394 FindAdjacent2(aList1, aListE1);
1395 aNE1 = aListE1.Extent();
1397 else { // result is compound of two ent.
1398 if (aNF1 == 2) //first ent. has 2 valid faces
1399 FindAdjacent2(aList1, aListE1); // find adjacent edges
1400 else if (aNF1 == 3) // first ent. has 3 valid faces
1401 FindAdjacent3(aList1, aListE1);
1402 else if (aNF1 == 4) //first ent. has 4 valid faces
1403 FindAdjacent4(aList1, aListE1);
1404 // set number of symmetry Edges of the first ent.
1405 aNE1 = aListE1.Extent();
1408 if (aNF2 == 2) //second ent. has 2 valid faces
1409 FindAdjacent2(aList2, aListE2);
1411 FindAdjacent3(aList2, aListE2);
1413 FindAdjacent4(aList2, aListE2);
1415 aNE2 = aListE2.Extent();
1417 //aListE1, aListE2 - contains Edges
1418 // if(aNE1 < 2) return;
1419 // check topological compatibility
1421 Handle(TDataStd_IntegerArray) aSAR;
1422 if(!ResultLabel().FindAttribute(TDataStd_IntegerArray::GetID(), aSAR) ) {
1423 aSAR = TDataStd_IntegerArray::Set(ResultLabel(), 1, 2);
1424 aSAR->SetValue(1, 0); //tag num for faces structure
1425 aSAR->SetValue(2, 0); //tag num for edges structure
1427 TDF_Label aLabelEDS;
1428 if(aSAR->Value(2)) aLabelEDS = ResultLabel().FindChild(aSAR->Value(2)); // !=0
1430 // initial creation of EDS structure
1431 aLabelEDS = NewShapes();
1432 aSAR->SetValue(2, aLabelEDS.Tag()); //keep tag
1434 Handle(TDataStd_Integer) anAtt;
1435 if(aLabelEDS.FindAttribute(TDataStd_Integer::GetID(), anAtt) ) {
1436 // modification : check compatibility
1437 if(anAtt->Get() != aNE1+aNE2) {
1438 cout << "WARNING: Case isn't mantained - Number of Edges was changed!"<<endl;
1439 // mark all structure as Deleted
1440 Standard_Integer aN = aLabelEDS.Tag()+anAtt->Get();
1441 for(Standard_Integer i=aLabelEDS.Tag(); i < aN; i++) {
1442 TDF_Label aLab = ResultLabel().FindChild(i, Standard_False);
1443 if(!aLab.IsNull()) {
1444 Handle(TNaming_NamedShape) aNS;
1445 if(aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
1446 TopoDS_Shape aShape = aNS->Get();
1447 TNaming_Builder aBuilder(aLab);
1448 aBuilder.Delete(aShape); //Deleted
1453 Handle(TDF_TagSource) aTS;
1454 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
1456 aTS->Set(aLabelEDS.Tag());
1457 anAtt->Set(aNE1+aNE2);
1461 TDataStd_Integer::Set(aLabelEDS, aNE1+aNE2); //keep number of edges
1464 // if(aNE1% 2 > 0) return;
1465 gp_Ax1 anAx = ComputeAxis(MS.Shape2());
1466 Handle(TDF_TagSource) aTS;
1467 ResultLabel().FindAttribute (TDF_TagSource::GetID (), aTS);
1468 if(!aNE2 && aNE1) { // only 1 ent.
1470 TopTools_Array1OfShape ArS1(1, aNE1);
1471 SortEdges(aListE1, anAx, ArS1);
1472 for(Standard_Integer i=1; i <= aNE1; i++) {
1473 TopoDS_Shape aShape = ArS1.Value(i);
1474 Standard_Integer aLabTag = aLabelEDS.Tag() + i -1;
1475 TDF_Label aLab = ResultLabel().FindChild(aLabTag);
1477 TNaming_Builder aBuilder(aLab);
1478 aBuilder.Generated(aShape);
1480 } else if(aNE1 && aNE2) { //2 ent.
1481 TopTools_Array1OfShape ArS1(1, aNE1);
1482 SortEdges(aListE1, anAx, ArS1);
1483 TopTools_Array1OfShape ArS2(1, aNE2);
1484 SortEdges(aListE2, anAx, ArS2);
1486 gp_Pnt aPnt1 = GetCenterPoint(aListE1.First());
1487 // gp_Pnt aPnt2 = GetCenterPoint(aListE2.First());
1488 if(IsDirectionPositive(anAx, anAx.Location(), aPnt1)) {
1490 for(i=1; i <= aNE1; i++) {
1491 TopoDS_Shape aShape = ArS1.Value(i);
1492 Standard_Integer aLabTag = aLabelEDS.Tag() + i - 1;
1493 TDF_Label aLab = ResultLabel().FindChild(aLabTag);
1495 TNaming_Builder aBuilder(aLab);
1496 aBuilder.Generated(aShape);
1498 Standard_Integer start = aLabelEDS.Tag() + aNE1;
1499 for(i=1; i <= aNE2; i++) {
1500 TopoDS_Shape aShape = ArS2.Value(i);
1501 Standard_Integer aLabTag = start + i - 1;
1502 TDF_Label aLab = ResultLabel().FindChild(aLabTag);
1504 TNaming_Builder aBuilder(aLab);
1505 aBuilder.Generated(aShape);
1510 for(i=1; i <= aNE2; i++) {
1511 TopoDS_Shape aShape = ArS2.Value(i);
1512 Standard_Integer aLabTag = aLabelEDS.Tag() + i - 1;
1513 TDF_Label aLab = ResultLabel().FindChild(aLabTag);
1515 TNaming_Builder aBuilder(aLab);
1516 aBuilder.Generated(aShape);
1518 Standard_Integer start = aLabelEDS.Tag() + aNE2;
1519 for(i=1; i <= aNE1; i++) {
1520 TopoDS_Shape aShape = ArS1.Value(i);
1521 Standard_Integer aLabTag = start + i - 1;
1522 TDF_Label aLab = ResultLabel().FindChild(aLabTag);
1524 TNaming_Builder aBuilder(aLab);
1525 aBuilder.Generated(aShape);
1531 //=======================================================================
1532 //function : ISWRCase2
1534 //=======================================================================
1535 Standard_Boolean QANewBRepNaming_BooleanOperationFeat::IsWRCase2(const BRepAlgoAPI_BooleanOperation& MS) {
1536 const TopoDS_Shape& Result = MS.Shape();
1537 const TopAbs_ShapeEnum& ResType = ShapeType(Result);
1538 if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return Standard_False;
1539 TopTools_ListOfShape aList;
1541 TopExp_Explorer anExp(Result, TopAbs_FACE);
1542 for(;anExp.More();anExp.Next()) {
1543 if(IsValidSurfType(TopoDS::Face(anExp.Current()))) {
1544 TopExp_Explorer anExp1(Result, TopAbs_FACE);
1545 for(;anExp1.More();anExp1.Next()) {
1546 if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) {
1547 TopTools_ListOfShape aList;
1548 aList.Append(anExp.Current());
1549 aList.Append(anExp1.Current());
1550 TopTools_ListOfShape anEList;
1551 FindAdjacent2(aList, anEList);
1552 if(anEList.Extent() == 2) {
1553 return Standard_True;
1559 return Standard_False;
1562 //=======================================================================
1563 //function : LoadWRCase
1565 //=======================================================================
1567 void QANewBRepNaming_BooleanOperationFeat::LoadWRCase(BRepAlgoAPI_BooleanOperation& MS) const {
1568 const TopoDS_Shape& Result = MS.Shape();
1569 const TopAbs_ShapeEnum& ResType = ShapeType(Result);
1570 if(ResType == TopAbs_COMPOUND || ResType >= TopAbs_FACE) return;
1571 TopTools_ListOfShape aList;
1573 TopExp_Explorer anExp(Result, TopAbs_FACE);
1574 for(;anExp.More();anExp.Next()) {
1575 if(IsValidSurfType(TopoDS::Face(anExp.Current()))) {
1576 TopExp_Explorer anExp1(Result, TopAbs_FACE);
1577 for(;anExp1.More();anExp1.Next()) {
1578 if(!anExp1.Current().IsSame(anExp.Current()) && !IsValidSurfType(TopoDS::Face(anExp1.Current()))) {
1579 TopTools_ListOfShape aList;
1580 aList.Append(anExp.Current());
1581 aList.Append(anExp1.Current());
1582 TopTools_ListOfShape anEList;
1583 FindAdjacent2(aList, anEList);
1584 if(anEList.Extent() == 2) {
1586 TopTools_ListIteratorOfListOfShape anEIt(anEList);
1587 GProp_GProps anE1Props, anE2Props;
1588 BRepGProp::LinearProperties(anEList.First(), anE1Props);
1589 BRepGProp::LinearProperties(anEList.Last(), anE2Props);
1591 const TDF_Label& WRE1Label = ResultLabel().NewChild();
1592 const TDF_Label& WRE2Label = ResultLabel().NewChild();
1593 const TDF_Label& WRV1Label = ResultLabel().NewChild();
1594 const TDF_Label& WRV2Label = ResultLabel().NewChild();
1596 TDataStd_Name::Set(WRE1Label, "WorkAroundEdge1");
1597 TDataStd_Name::Set(WRE2Label, "WorkAroundEdge2");
1598 TDataStd_Name::Set(WRV1Label, "WorkAroundVertex1");
1599 TDataStd_Name::Set(WRV2Label, "WorkAroundVertex2");
1602 TNaming_Builder anEBuilder1(WRE1Label);
1603 TNaming_Builder anEBuilder2(WRE2Label);
1604 TNaming_Builder aVBuilder1(WRV1Label);
1605 TNaming_Builder aVBuilder2(WRV2Label);
1607 if(anE1Props.Mass() > anE2Props.Mass()) {
1608 anEBuilder1.Generated(anEList.Last());
1609 anEBuilder2.Generated(anEList.First());
1610 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.Last())));
1611 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.Last())));
1613 anEBuilder1.Generated(anEList.First());
1614 anEBuilder2.Generated(anEList.Last());
1615 aVBuilder1.Generated(TopExp::FirstVertex(TopoDS::Edge(anEList.First())));
1616 aVBuilder2.Generated(TopExp::LastVertex(TopoDS::Edge(anEList.First())));