1 // Created on: 1995-10-20
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_Surface.hxx>
19 #include <BOPTools_AlgoTools.hxx>
20 #include <BOPTools_AlgoTools3D.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRepOffset_Analyse.hxx>
26 #include <BRepOffset_Interval.hxx>
27 #include <BRepOffset_ListIteratorOfListOfInterval.hxx>
28 #include <BRepOffset_Tool.hxx>
29 #include <BRepPrimAPI_MakePrism.hxx>
30 #include <BRepTools.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Surface.hxx>
37 #include <gp_Pnt2d.hxx>
39 #include <IntTools_Context.hxx>
40 #include <Precision.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <TopoDS_Compound.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Face.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
50 #include <TopTools_MapOfShape.hxx>
53 static void CorrectOrientationOfTangent(gp_Vec& TangVec,
54 const TopoDS_Vertex& aVertex,
55 const TopoDS_Edge& anEdge)
57 TopoDS_Vertex Vlast = TopExp::LastVertex(anEdge);
58 if (aVertex.IsSame(Vlast))
61 //=======================================================================
62 //function : BRepOffset_Analyse
64 //=======================================================================
66 BRepOffset_Analyse::BRepOffset_Analyse()
67 : myOffset (0.0), myDone (Standard_False)
71 //=======================================================================
72 //function : BRepOffset_Analyse
74 //=======================================================================
75 BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
76 const Standard_Real Angle)
77 : myOffset (0.0), myDone (Standard_False)
82 //=======================================================================
83 //function : EdgeAnlyse
85 //=======================================================================
86 static void EdgeAnalyse(const TopoDS_Edge& E,
87 const TopoDS_Face& F1,
88 const TopoDS_Face& F2,
89 const Standard_Real SinTol,
90 BRepOffset_ListOfInterval& LI)
94 BRep_Tool::Range(E, F1, f, l);
95 BRepOffset_Interval I;
96 I.First(f); I.Last(l);
98 // Tangent if the regularity is at least G1.
99 if (BRep_Tool::HasContinuity(E,F1,F2)) {
100 if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
101 I.Type(ChFiDS_Tangential);
107 ChFiDS_TypeOfConcavity aType = ChFi3d::DefineConnectType(E, F1, F2,
108 SinTol, Standard_False);
109 if(aType != ChFiDS_Tangential)
111 aType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_True);
117 //=======================================================================
118 //function : BuildAncestors
120 //=======================================================================
121 static void BuildAncestors (const TopoDS_Shape& S,
122 TopTools_IndexedDataMapOfShapeListOfShape& MA)
125 TopExp::MapShapesAndUniqueAncestors(S,TopAbs_VERTEX,TopAbs_EDGE,MA);
126 TopExp::MapShapesAndUniqueAncestors(S,TopAbs_EDGE ,TopAbs_FACE,MA);
129 //=======================================================================
132 //=======================================================================
133 void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
134 const Standard_Real Angle)
139 myReplacement.Clear();
140 myDescendants.Clear();
143 Standard_Real SinTol = Abs (Sin(Angle));
146 BuildAncestors (S,myAncestors);
148 TopTools_ListOfShape aLETang;
150 TopExp_Explorer Exp(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
151 for ( ; Exp.More(); Exp.Next()) {
152 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
153 if (!myMapEdgeType.IsBound(E)) {
154 BRepOffset_ListOfInterval LI;
155 myMapEdgeType.Bind(E,LI);
157 const TopTools_ListOfShape& L = Ancestors(E);
161 if (L.Extent() == 2) {
162 const TopoDS_Face& F1 = TopoDS::Face (L.First());
163 const TopoDS_Face& F2 = TopoDS::Face (L.Last());
164 EdgeAnalyse (E, F1, F2, SinTol, myMapEdgeType (E));
166 // For tangent faces add artificial perpendicular face
167 // to close the gap between them (if they have different offset values)
168 if (myMapEdgeType(E).Last().Type() == ChFiDS_Tangential)
171 else if (L.Extent() == 1) {
172 Standard_Real U1, U2;
173 const TopoDS_Face& F = TopoDS::Face (L.First());
174 BRep_Tool::Range (E, F, U1, U2);
175 BRepOffset_Interval Inter (U1, U2, ChFiDS_Other);
177 if (!BRepTools::IsReallyClosed (E, F)) {
178 Inter.Type (ChFiDS_FreeBound);
180 myMapEdgeType (E).Append (Inter);
184 std::cout <<"edge shared by more than two faces"<<std::endl;
190 TreatTangentFaces (aLETang);
191 myDone = Standard_True;
194 //=======================================================================
195 //function : Generated
197 //=======================================================================
198 void BRepOffset_Analyse::TreatTangentFaces (const TopTools_ListOfShape& theLE)
200 if (theLE.IsEmpty() || myFaceOffsetMap.IsEmpty())
202 // Noting to do: either there are no tangent faces in the shape or
203 // the face offset map has not been provided
207 // Select the edges which connect faces with different offset values
208 TopoDS_Compound aCETangent;
209 BRep_Builder().MakeCompound (aCETangent);
210 // Bind to each tangent edge a max offset value of its faces
211 TopTools_DataMapOfShapeReal anEdgeOffsetMap;
212 // Bind vertices of the tangent edges with connected edges
213 // of the face with smaller offset value
214 TopTools_DataMapOfShapeShape aDMVEMin;
215 for (TopTools_ListOfShape::Iterator it (theLE); it.More(); it.Next())
217 const TopoDS_Shape& aE = it.Value();
218 const TopTools_ListOfShape& aLA = Ancestors (aE);
220 const TopoDS_Shape& aF1 = aLA.First(), aF2 = aLA.Last();
222 const Standard_Real *pOffsetVal1 = myFaceOffsetMap.Seek (aF1);
223 const Standard_Real *pOffsetVal2 = myFaceOffsetMap.Seek (aF2);
224 const Standard_Real anOffsetVal1 = pOffsetVal1 ? Abs (*pOffsetVal1) : myOffset;
225 const Standard_Real anOffsetVal2 = pOffsetVal2 ? Abs (*pOffsetVal2) : myOffset;
226 if (anOffsetVal1 != anOffsetVal2)
228 BRep_Builder().Add (aCETangent, aE);
229 anEdgeOffsetMap.Bind (aE, Max (anOffsetVal1, anOffsetVal2));
231 const TopoDS_Shape& aFMin = anOffsetVal1 < anOffsetVal2 ? aF1 : aF2;
232 for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
234 const TopoDS_Shape& aV = itV.Value();
235 if (Ancestors (aV).Extent() == 3)
237 for (TopExp_Explorer expE (aFMin, TopAbs_EDGE); expE.More(); expE.Next())
239 const TopoDS_Shape& aEMin = expE.Current();
240 if (aEMin.IsSame (aE))
242 for (TopoDS_Iterator itV1 (aEMin); itV1.More(); itV1.Next())
244 const TopoDS_Shape& aVx = itV1.Value();
246 aDMVEMin.Bind (aV, aEMin);
254 if (anEdgeOffsetMap.IsEmpty())
257 // Create map of Face ancestors for the vertices on tangent edges
258 TopTools_DataMapOfShapeListOfShape aDMVFAnc;
260 for (TopTools_ListOfShape::Iterator itE (theLE); itE.More(); itE.Next())
262 const TopoDS_Shape& aE = itE.Value();
263 if (!anEdgeOffsetMap.IsBound (aE))
266 TopTools_MapOfShape aMFence;
268 const TopTools_ListOfShape& aLEA = Ancestors (aE);
269 for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
270 aMFence.Add (itLEA.Value());
273 for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
275 const TopoDS_Shape& aV = itV.Value();
276 TopTools_ListOfShape* pLFA = aDMVFAnc.Bound (aV, TopTools_ListOfShape());
277 const TopTools_ListOfShape& aLVA = Ancestors (aV);
278 for (TopTools_ListOfShape::Iterator itLVA (aLVA); itLVA.More(); itLVA.Next())
280 const TopoDS_Edge& aEA = TopoDS::Edge (itLVA.Value());
281 const BRepOffset_ListOfInterval* pIntervals = myMapEdgeType.Seek (aEA);
282 if (!pIntervals || pIntervals->IsEmpty())
284 if (pIntervals->First().Type() == ChFiDS_Tangential)
287 const TopTools_ListOfShape& aLEA = Ancestors (aEA);
288 for (TopTools_ListOfShape::Iterator itLEA (aLEA); itLEA.More(); itLEA.Next())
290 const TopoDS_Shape& aFA = itLEA.Value();
291 if (aMFence.Add (aFA))
298 Handle(IntTools_Context) aCtx = new IntTools_Context();
300 Standard_Real aSinTol = Abs (Sin (myAngle));
302 // Make blocks of connected edges
303 TopTools_ListOfListOfShape aLCB;
304 TopTools_IndexedDataMapOfShapeListOfShape aMVEMap;
306 BOPTools_AlgoTools::MakeConnexityBlocks (aCETangent, TopAbs_VERTEX, TopAbs_EDGE, aLCB, aMVEMap);
308 // Analyze each block to find co-planar edges
309 for (TopTools_ListOfListOfShape::Iterator itLCB (aLCB); itLCB.More(); itLCB.Next())
311 const TopTools_ListOfShape& aCB = itLCB.Value();
313 TopTools_MapOfShape aMFence;
314 for (TopTools_ListOfShape::Iterator itCB1 (aCB); itCB1.More(); itCB1.Next())
316 const TopoDS_Edge& aE1 = TopoDS::Edge (itCB1.Value());
317 if (!aMFence.Add (aE1))
320 TopoDS_Compound aBlock;
321 BRep_Builder().MakeCompound (aBlock);
322 BRep_Builder().Add (aBlock, aE1.Oriented (TopAbs_FORWARD));
324 Standard_Real anOffset = anEdgeOffsetMap.Find (aE1);
325 const TopTools_ListOfShape& aLF1 = Ancestors (aE1);
328 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE1, TopoDS::Face (aLF1.First()), aDN1);
330 TopTools_ListOfShape::Iterator itCB2 = itCB1;
331 for (itCB2.Next(); itCB2.More(); itCB2.Next())
333 const TopoDS_Edge& aE2 = TopoDS::Edge (itCB2.Value());
334 if (aMFence.Contains (aE2))
337 const TopTools_ListOfShape& aLF2 = Ancestors (aE2);
340 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE2, TopoDS::Face (aLF2.First()), aDN2);
342 if (aDN1.XYZ().Crossed (aDN2.XYZ()).Modulus() < aSinTol)
344 BRep_Builder().Add (aBlock, aE2.Oriented (TopAbs_FORWARD));
346 anOffset = Max (anOffset, anEdgeOffsetMap.Find (aE2));
351 BRepPrimAPI_MakePrism aMP (aBlock, gp_Vec (aDN1.XYZ()) * anOffset);
355 TopTools_IndexedDataMapOfShapeListOfShape aPrismAncestors;
356 TopExp::MapShapesAndAncestors (aMP.Shape(), TopAbs_EDGE, TopAbs_FACE, aPrismAncestors);
357 TopExp::MapShapesAndAncestors (aMP.Shape(), TopAbs_VERTEX, TopAbs_EDGE, aPrismAncestors);
359 for (TopoDS_Iterator itE (aBlock); itE.More(); itE.Next())
361 const TopoDS_Edge& aE = TopoDS::Edge (itE.Value());
362 const TopTools_ListOfShape& aLG = aMP.Generated (aE);
363 TopoDS_Face aFNew = TopoDS::Face (aLG.First());
365 TopTools_ListOfShape& aLA = myAncestors.ChangeFromKey (aE);
367 TopoDS_Shape aF1 = aLA.First();
368 TopoDS_Shape aF2 = aLA.Last();
370 const Standard_Real *pOffsetVal1 = myFaceOffsetMap.Seek (aF1);
371 const Standard_Real *pOffsetVal2 = myFaceOffsetMap.Seek (aF2);
372 const Standard_Real anOffsetVal1 = pOffsetVal1 ? Abs (*pOffsetVal1) : myOffset;
373 const Standard_Real anOffsetVal2 = pOffsetVal2 ? Abs (*pOffsetVal2) : myOffset;
375 const TopoDS_Shape& aFToRemove = anOffsetVal1 > anOffsetVal2 ? aF1 : aF2;
376 const TopoDS_Shape& aFOpposite = anOffsetVal1 > anOffsetVal2 ? aF2 : aF1;
378 // Orient the face so its normal is directed to smaller offset face
380 // get normal of the new face
382 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aFNew, aDN);
384 // get bi-normal for the aFOpposite
386 for (TopExp_Explorer aExpE (aFOpposite, TopAbs_EDGE); aExpE.More(); aExpE.Next())
388 if (aE.IsSame (aExpE.Current()))
390 aEInF = TopoDS::Edge (aExpE.Current());
398 const Handle(Geom_Curve)& aC3D = BRep_Tool::Curve (aEInF, f, l);
399 gp_Pnt aPOnE = aC3D->Value ((f + l) / 2.);
400 BOPTools_AlgoTools3D::PointNearEdge (aEInF, TopoDS::Face (aFOpposite), (f + l) / 2., 1.e-5, aP2d, aPInF);
402 gp_Vec aBN (aPOnE, aPInF);
404 if (aBN.Dot (aDN) < 0)
408 // Remove the face with bigger offset value from edge ancestors
409 for (TopTools_ListOfShape::Iterator itA (aLA); itA.More();itA.Next())
411 if (itA.Value().IsSame (aFToRemove))
419 myMapEdgeType (aE).Clear();
420 // Analyze edge again
421 EdgeAnalyse (aE, TopoDS::Face (aFOpposite), aFNew, aSinTol, myMapEdgeType (aE));
424 TopTools_MapOfShape aFNewEdgeMap;
425 aFNewEdgeMap.Add (aE);
426 for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
428 const TopoDS_Shape& aV = itV.Value();
429 // Add Side edge to map of Ancestors with the correct orientation
430 TopoDS_Edge aEG = TopoDS::Edge (aMP.Generated (aV).First());
431 myGenerated.Bind (aV, aEG);
433 for (TopExp_Explorer anExpEg (aFNew, TopAbs_EDGE); anExpEg.More(); anExpEg.Next())
435 if (anExpEg.Current().IsSame (aEG))
437 aEG = TopoDS::Edge (anExpEg.Current());
443 if (aDMVEMin.IsBound (aV))
445 const TopTools_ListOfShape* pSA = aDMVFAnc.Seek (aV);
446 if (pSA && pSA->Extent() == 1)
448 // Adjust orientation of generated edge to its new ancestor
449 TopoDS_Edge aEMin = TopoDS::Edge (aDMVEMin.Find (aV));
450 for (TopExp_Explorer expEx (pSA->First(), TopAbs_EDGE); expEx.More(); expEx.Next())
452 if (expEx.Current().IsSame (aEMin))
454 aEMin = TopoDS::Edge (expEx.Current());
459 TopAbs_Orientation anOriInEMin (TopAbs_FORWARD), anOriInEG (TopAbs_FORWARD);
461 for (TopoDS_Iterator itx (aEMin); itx.More(); itx.Next())
463 if (itx.Value().IsSame (aV))
465 anOriInEMin = itx.Value().Orientation();
470 for (TopoDS_Iterator itx (aEG); itx.More(); itx.Next())
472 if (itx.Value().IsSame (aV))
474 anOriInEG = itx.Value().Orientation();
479 if (anOriInEG == anOriInEMin)
484 TopTools_ListOfShape& aLVA = myAncestors.ChangeFromKey (aV);
485 if (!aLVA.Contains (aEG))
487 aFNewEdgeMap.Add (aEG);
489 TopTools_ListOfShape& aLEGA =
490 myAncestors (myAncestors.Add (aEG, aPrismAncestors.FindFromKey (aEG)));
492 // Add ancestors from the shape
493 const TopTools_ListOfShape* pSA = aDMVFAnc.Seek (aV);
494 if (pSA && !pSA->IsEmpty())
496 TopTools_ListOfShape aLSA = *pSA;
501 myMapEdgeType.Bind (aEG, BRepOffset_ListOfInterval());
502 if (aLEGA.Extent() == 2)
504 EdgeAnalyse (aEG, TopoDS::Face (aLEGA.First()), TopoDS::Face (aLEGA.Last()),
505 aSinTol, myMapEdgeType (aEG));
509 // Find an edge opposite to tangential one and add ancestors for it
510 TopoDS_Edge aEOpposite;
511 for (TopExp_Explorer anExpE (aFNew, TopAbs_EDGE); anExpE.More(); anExpE.Next())
513 if (!aFNewEdgeMap.Contains (anExpE.Current()))
515 aEOpposite = TopoDS::Edge (anExpE.Current());
521 // Find it in aFOpposite
522 for (TopExp_Explorer anExpE (aFToRemove, TopAbs_EDGE); anExpE.More(); anExpE.Next())
524 const TopoDS_Shape& aEInFToRem = anExpE.Current();
525 if (aE.IsSame (aEInFToRem))
527 if (BOPTools_AlgoTools::IsSplitToReverse (aEOpposite, aEInFToRem, aCtx))
528 aEOpposite.Reverse();
534 TopTools_ListOfShape aLFOpposite;
535 aLFOpposite.Append (aFNew);
536 aLFOpposite.Append (aFToRemove);
537 myAncestors.Add (aEOpposite, aLFOpposite);
538 myMapEdgeType.Bind (aEOpposite, BRepOffset_ListOfInterval());
539 EdgeAnalyse (aEOpposite, aFNew, TopoDS::Face (aFToRemove), aSinTol, myMapEdgeType (aEOpposite));
541 TopTools_DataMapOfShapeShape* pEEMap = myReplacement.ChangeSeek (aFToRemove);
543 pEEMap = myReplacement.Bound (aFToRemove, TopTools_DataMapOfShapeShape());
544 pEEMap->Bind (aE, aEOpposite);
546 // Add ancestors for the vertices
547 for (TopoDS_Iterator itV (aEOpposite); itV.More(); itV.Next())
549 const TopoDS_Shape& aV = itV.Value();
550 const TopTools_ListOfShape& aLVA = aPrismAncestors.FindFromKey (aV);
551 myAncestors.Add (aV, aLVA);
554 myNewFaces.Append (aFNew);
555 myGenerated.Bind (aE, aFNew);
561 //=======================================================================
562 //function : EdgeReplacement
564 //=======================================================================
565 const TopoDS_Edge& BRepOffset_Analyse::EdgeReplacement (const TopoDS_Face& theF,
566 const TopoDS_Edge& theE) const
568 const TopTools_DataMapOfShapeShape* pEE = myReplacement.Seek (theF);
572 const TopoDS_Shape* pE = pEE->Seek (theE);
576 return TopoDS::Edge (*pE);
579 //=======================================================================
580 //function : Generated
582 //=======================================================================
583 TopoDS_Shape BRepOffset_Analyse::Generated (const TopoDS_Shape& theS) const
585 static TopoDS_Shape aNullShape;
586 const TopoDS_Shape* pGenS = myGenerated.Seek (theS);
587 return pGenS ? *pGenS : aNullShape;
590 //=======================================================================
591 //function : Descendants
593 //=======================================================================
594 const TopTools_ListOfShape* BRepOffset_Analyse::Descendants (const TopoDS_Shape& theS,
595 const Standard_Boolean theUpdate) const
597 if (myDescendants.IsEmpty() || theUpdate)
599 myDescendants.Clear();
600 const Standard_Integer aNbA = myAncestors.Extent();
601 for (Standard_Integer i = 1; i <= aNbA; ++i)
603 const TopoDS_Shape& aSS = myAncestors.FindKey (i);
604 const TopTools_ListOfShape& aLA = myAncestors (i);
606 for (TopTools_ListOfShape::Iterator it (aLA); it.More(); it.Next())
608 const TopoDS_Shape& aSA = it.Value();
610 TopTools_ListOfShape* pLD = myDescendants.ChangeSeek (aSA);
612 pLD = myDescendants.Bound (aSA, TopTools_ListOfShape());
613 if (!pLD->Contains (aSS))
619 return myDescendants.Seek (theS);
622 //=======================================================================
625 //=======================================================================
626 void BRepOffset_Analyse::Clear()
628 myDone = Standard_False;
630 myMapEdgeType.Clear();
631 myAncestors .Clear();
632 myFaceOffsetMap.Clear();
633 myReplacement.Clear();
634 myDescendants.Clear();
639 //=======================================================================
640 //function : BRepOffset_ListOfInterval&
642 //=======================================================================
643 const BRepOffset_ListOfInterval& BRepOffset_Analyse::Type(const TopoDS_Edge& E) const
645 return myMapEdgeType (E);
648 //=======================================================================
651 //=======================================================================
652 void BRepOffset_Analyse::Edges(const TopoDS_Vertex& V,
653 const ChFiDS_TypeOfConcavity T,
654 TopTools_ListOfShape& LE) const
657 const TopTools_ListOfShape& L = Ancestors (V);
658 TopTools_ListIteratorOfListOfShape it(L);
660 for ( ;it.More(); it.Next()) {
661 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
662 const BRepOffset_ListOfInterval *pIntervals = myMapEdgeType.Seek (E);
663 if (pIntervals && pIntervals->Extent() > 0)
666 BRepOffset_Tool::EdgeVertices (E,V1,V2);
668 if (pIntervals->Last().Type() == T)
672 if (pIntervals->First().Type() == T)
680 //=======================================================================
683 //=======================================================================
684 void BRepOffset_Analyse::Edges(const TopoDS_Face& F,
685 const ChFiDS_TypeOfConcavity T,
686 TopTools_ListOfShape& LE) const
689 TopExp_Explorer exp(F, TopAbs_EDGE);
691 for ( ;exp.More(); exp.Next()) {
692 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
694 const BRepOffset_ListOfInterval& Lint = Type(E);
695 BRepOffset_ListIteratorOfListOfInterval it(Lint);
696 for ( ;it.More(); it.Next()) {
697 if (it.Value().Type() == T) LE.Append(E);
702 //=======================================================================
703 //function : TangentEdges
705 //=======================================================================
706 void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge ,
707 const TopoDS_Vertex& Vertex,
708 TopTools_ListOfShape& Edges ) const
712 Standard_Real U,URef;
713 BRepAdaptor_Curve C3d, C3dRef;
715 URef = BRep_Tool::Parameter(Vertex,Edge);
716 C3dRef = BRepAdaptor_Curve(Edge);
717 VRef = C3dRef.DN(URef,1);
718 CorrectOrientationOfTangent(VRef, Vertex, Edge);
719 if (VRef.SquareMagnitude() < gp::Resolution()) return;
723 const TopTools_ListOfShape& Anc = Ancestors(Vertex);
724 TopTools_ListIteratorOfListOfShape it(Anc);
725 for ( ; it.More(); it.Next()) {
726 const TopoDS_Edge& CurE = TopoDS::Edge(it.Value());
727 if ( CurE.IsSame(Edge)) continue;
728 U = BRep_Tool::Parameter(Vertex,CurE);
729 C3d = BRepAdaptor_Curve(CurE);
731 CorrectOrientationOfTangent(V, Vertex, CurE);
732 if (V.SquareMagnitude() < gp::Resolution()) continue;
733 if (V.IsOpposite(VRef,myAngle)) {
739 //=======================================================================
742 //=======================================================================
743 void BRepOffset_Analyse::Explode (TopTools_ListOfShape& List,
744 const ChFiDS_TypeOfConcavity T) const
748 TopTools_MapOfShape Map;
750 TopExp_Explorer Fexp;
751 for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) {
752 if ( Map.Add(Fexp.Current())) {
753 TopoDS_Face Face = TopoDS::Face(Fexp.Current());
757 // add to Co all faces from the cloud of faces
758 // G1 created from <Face>
759 AddFaces(Face,Co,Map,T);
765 //=======================================================================
768 //=======================================================================
769 void BRepOffset_Analyse::Explode (TopTools_ListOfShape& List,
770 const ChFiDS_TypeOfConcavity T1,
771 const ChFiDS_TypeOfConcavity T2) const
775 TopTools_MapOfShape Map;
777 TopExp_Explorer Fexp;
778 for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) {
779 if ( Map.Add(Fexp.Current())) {
780 TopoDS_Face Face = TopoDS::Face(Fexp.Current());
784 // add to Co all faces from the cloud of faces
785 // G1 created from <Face>
786 AddFaces(Face,Co,Map,T1,T2);
792 //=======================================================================
793 //function : AddFaces
795 //=======================================================================
796 void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
798 TopTools_MapOfShape& Map,
799 const ChFiDS_TypeOfConcavity T) const
802 const TopTools_ListOfShape *pLE = Descendants (Face);
805 for (TopTools_ListOfShape::Iterator it (*pLE); it.More(); it.Next())
807 const TopoDS_Edge& E = TopoDS::Edge (it.Value());
808 const BRepOffset_ListOfInterval& LI = Type(E);
809 if (!LI.IsEmpty() && LI.First().Type() == T) {
810 // so <NewFace> is attached to G1 by <Face>
811 const TopTools_ListOfShape& L = Ancestors(E);
812 if (L.Extent() == 2) {
813 TopoDS_Face F1 = TopoDS::Face (L.First());
814 if (F1.IsSame (Face))
815 F1 = TopoDS::Face (L.Last());
818 AddFaces (F1, Co, Map, T);
825 //=======================================================================
826 //function : AddFaces
828 //=======================================================================
829 void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
831 TopTools_MapOfShape& Map,
832 const ChFiDS_TypeOfConcavity T1,
833 const ChFiDS_TypeOfConcavity T2) const
836 const TopTools_ListOfShape *pLE = Descendants (Face);
839 for (TopTools_ListOfShape::Iterator it (*pLE); it.More(); it.Next())
841 const TopoDS_Edge& E = TopoDS::Edge (it.Value());
842 const BRepOffset_ListOfInterval& LI = Type(E);
844 (LI.First().Type() == T1 || LI.First().Type() == T2)) {
845 // so <NewFace> is attached to G1 by <Face>
846 const TopTools_ListOfShape& L = Ancestors(E);
847 if (L.Extent() == 2) {
848 TopoDS_Face F1 = TopoDS::Face (L.First());
849 if (F1.IsSame (Face))
850 F1 = TopoDS::Face (L.Last());
853 AddFaces (F1, Co, Map, T1, T2);