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 <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepOffset_Analyse.hxx>
24 #include <BRepOffset_Interval.hxx>
25 #include <BRepOffset_ListIteratorOfListOfInterval.hxx>
26 #include <BRepOffset_Tool.hxx>
27 #include <BRepTools.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_Surface.hxx>
34 #include <gp_Pnt2d.hxx>
36 #include <Precision.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <TopoDS_Compound.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Shape.hxx>
44 #include <TopoDS_Vertex.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
49 static void CorrectOrientationOfTangent(gp_Vec& TangVec,
50 const TopoDS_Vertex& aVertex,
51 const TopoDS_Edge& anEdge)
53 TopoDS_Vertex Vlast = TopExp::LastVertex(anEdge);
54 if (aVertex.IsSame(Vlast))
57 //=======================================================================
58 //function : BRepOffset_Analyse
60 //=======================================================================
62 BRepOffset_Analyse::BRepOffset_Analyse()
63 :myDone(Standard_False)
68 //=======================================================================
69 //function : BRepOffset_Analyse
71 //=======================================================================
73 BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
74 const Standard_Real Angle)
75 :myDone(Standard_False)
80 //=======================================================================
81 //function : EdgeAnlyse
83 //=======================================================================
85 static void EdgeAnalyse(const TopoDS_Edge& E,
86 const TopoDS_Face& F1,
87 const TopoDS_Face& F2,
88 const Standard_Real SinTol,
89 BRepOffset_ListOfInterval& LI)
93 BRep_Tool::Range(E, F1, f, l);
94 BRepOffset_Interval I;
95 I.First(f); I.Last(l);
97 // Tangent if the regularity is at least G1.
98 if (BRep_Tool::HasContinuity(E,F1,F2)) {
99 if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
100 I.Type(ChFiDS_Tangential);
106 ChFiDS_TypeOfConcavity aType = ChFi3d::DefineConnectType(E, F1, F2,
107 SinTol, Standard_False);
108 if(aType != ChFiDS_Tangential)
110 aType = ChFi3d::DefineConnectType(E, F1, F2, SinTol, Standard_True);
116 //=======================================================================
117 //function : BuildAncestors
119 //=======================================================================
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 //=======================================================================
134 Standard_Boolean BRepOffset_Analyse::IsDone() const
140 //=======================================================================
143 //=======================================================================
145 void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
146 const Standard_Real Angle)
151 Standard_Real SinTol = Sin(Angle);
154 BuildAncestors (S,ancestors);
157 TopExp_Explorer Exp(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
158 for ( ; Exp.More(); Exp.Next()) {
159 const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
160 if (!mapEdgeType.IsBound(E)) {
161 BRepOffset_ListOfInterval LI;
162 mapEdgeType.Bind(E,LI);
164 const TopTools_ListOfShape& L = Ancestors(E);
168 if (L.Extent() == 2) {
169 const TopoDS_Face& F1 = TopoDS::Face(L.First());
170 const TopoDS_Face& F2 = TopoDS::Face(L.Last ());
171 EdgeAnalyse(E,F1,F2,SinTol,mapEdgeType(E));
173 else if (L.Extent() == 1) {
175 const TopoDS_Face& F = TopoDS::Face(L.First());
176 BRep_Tool::Range(E,F,U1,U2);
177 BRepOffset_Interval Inter(U1,U2,ChFiDS_Other);
179 if (! BRepTools::IsReallyClosed(E,F)) {
180 Inter.Type(ChFiDS_FreeBound);
182 mapEdgeType(E).Append(Inter);
186 std::cout <<"edge shared by more than two faces"<<std::endl;
191 myDone = Standard_True;
194 //=======================================================================
197 //=======================================================================
199 void BRepOffset_Analyse::Clear()
201 myDone = Standard_False;
211 //=======================================================================
212 //function : BRepOffset_ListOfInterval&
214 //=======================================================================
216 const BRepOffset_ListOfInterval& BRepOffset_Analyse::Type(const TopoDS_Edge& E)
219 return mapEdgeType (E);
223 //=======================================================================
226 //=======================================================================
228 void BRepOffset_Analyse::Edges(const TopoDS_Vertex& V,
229 const ChFiDS_TypeOfConcavity T,
230 TopTools_ListOfShape& LE)
234 const TopTools_ListOfShape& L = Ancestors (V);
235 TopTools_ListIteratorOfListOfShape it(L);
237 for ( ;it.More(); it.Next()) {
238 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
240 BRepOffset_Tool::EdgeVertices (E,V1,V2);
242 if (mapEdgeType(E).Last().Type() == T)
246 if (mapEdgeType(E).First().Type() == T)
253 //=======================================================================
256 //=======================================================================
258 void BRepOffset_Analyse::Edges(const TopoDS_Face& F,
259 const ChFiDS_TypeOfConcavity T,
260 TopTools_ListOfShape& LE)
264 TopExp_Explorer exp(F, TopAbs_EDGE);
266 for ( ;exp.More(); exp.Next()) {
267 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
269 const BRepOffset_ListOfInterval& Lint = Type(E);
270 BRepOffset_ListIteratorOfListOfInterval it(Lint);
271 for ( ;it.More(); it.Next()) {
272 if (it.Value().Type() == T) LE.Append(E);
277 //=======================================================================
278 //function : TangentEdges
280 //=======================================================================
282 void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge& Edge ,
283 const TopoDS_Vertex& Vertex,
284 TopTools_ListOfShape& Edges ) const
289 Standard_Real U,URef;
290 BRepAdaptor_Curve C3d, C3dRef;
292 URef = BRep_Tool::Parameter(Vertex,Edge);
293 C3dRef = BRepAdaptor_Curve(Edge);
294 VRef = C3dRef.DN(URef,1);
295 CorrectOrientationOfTangent(VRef, Vertex, Edge);
296 if (VRef.SquareMagnitude() < gp::Resolution()) return;
300 const TopTools_ListOfShape& Anc = Ancestors(Vertex);
301 TopTools_ListIteratorOfListOfShape it(Anc);
302 for ( ; it.More(); it.Next()) {
303 const TopoDS_Edge& CurE = TopoDS::Edge(it.Value());
304 if ( CurE.IsSame(Edge)) continue;
305 U = BRep_Tool::Parameter(Vertex,CurE);
306 C3d = BRepAdaptor_Curve(CurE);
308 CorrectOrientationOfTangent(V, Vertex, CurE);
309 if (V.SquareMagnitude() < gp::Resolution()) continue;
310 if (V.IsOpposite(VRef,angle)) {
318 //=======================================================================
319 //function : HasAncestor
321 //=======================================================================
323 Standard_Boolean BRepOffset_Analyse::HasAncestor (const TopoDS_Shape& S) const
325 return ancestors.Contains(S);
329 //=======================================================================
330 //function : Ancestors
332 //=======================================================================
334 const TopTools_ListOfShape& BRepOffset_Analyse::Ancestors
335 (const TopoDS_Shape& S) const
337 return ancestors.FindFromKey(S);
341 //=======================================================================
344 //=======================================================================
346 void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
347 const ChFiDS_TypeOfConcavity T ) const
351 TopTools_MapOfShape Map;
353 TopExp_Explorer Fexp;
354 for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) {
355 if ( Map.Add(Fexp.Current())) {
356 TopoDS_Face Face = TopoDS::Face(Fexp.Current());
360 // add to Co all faces from the cloud of faces
361 // G1 created from <Face>
362 AddFaces(Face,Co,Map,T);
368 //=======================================================================
371 //=======================================================================
373 void BRepOffset_Analyse::Explode( TopTools_ListOfShape& List,
374 const ChFiDS_TypeOfConcavity T1,
375 const ChFiDS_TypeOfConcavity T2) const
379 TopTools_MapOfShape Map;
381 TopExp_Explorer Fexp;
382 for (Fexp.Init(myShape,TopAbs_FACE); Fexp.More(); Fexp.Next()) {
383 if ( Map.Add(Fexp.Current())) {
384 TopoDS_Face Face = TopoDS::Face(Fexp.Current());
388 // add to Co all faces from the cloud of faces
389 // G1 created from <Face>
390 AddFaces(Face,Co,Map,T1,T2);
397 //=======================================================================
398 //function : AddFaces
400 //=======================================================================
402 void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
404 TopTools_MapOfShape& Map,
405 const ChFiDS_TypeOfConcavity T) const
408 TopExp_Explorer exp(Face,TopAbs_EDGE);
409 for ( ; exp.More(); exp.Next()) {
410 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
411 const BRepOffset_ListOfInterval& LI = Type(E);
412 if (!LI.IsEmpty() && LI.First().Type() == T) {
413 // so <NewFace> is attached to G1 by <Face>
414 const TopTools_ListOfShape& L = Ancestors(E);
415 if (L.Extent() == 2) {
416 TopoDS_Face F1 = TopoDS::Face(L.First());
417 if ( F1.IsSame(Face))
418 F1 = TopoDS::Face(L.Last ());
421 AddFaces(F1,Co,Map,T);
427 //=======================================================================
428 //function : AddFaces
430 //=======================================================================
432 void BRepOffset_Analyse::AddFaces (const TopoDS_Face& Face,
434 TopTools_MapOfShape& Map,
435 const ChFiDS_TypeOfConcavity T1,
436 const ChFiDS_TypeOfConcavity T2) const
439 TopExp_Explorer exp(Face,TopAbs_EDGE);
440 for ( ; exp.More(); exp.Next()) {
441 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
442 const BRepOffset_ListOfInterval& LI = Type(E);
444 (LI.First().Type() == T1 || LI.First().Type() == T2)) {
445 // so <NewFace> is attached to G1 by <Face>
446 const TopTools_ListOfShape& L = Ancestors(E);
447 if (L.Extent() == 2) {
448 TopoDS_Face F1 = TopoDS::Face(L.First());
449 if ( F1.IsSame(Face))
450 F1 = TopoDS::Face(L.Last ());
453 AddFaces(F1,Co,Map,T1,T2);