1 // Created on: 1995-09-18
2 // Created by: Bruno DUMORTIER
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.
17 #include <BRepOffsetAPI_MakeOffset.ixx>
18 #include <BRepBuilderAPI_MakeFace.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAlgo_FaceRestrictor.hxx>
22 #include <Extrema_ExtPS.hxx>
23 #include <BRepAdaptor_Surface.hxx>
24 #include <BRepFill_OffsetWire.hxx>
25 #include <BRepFill_ListIteratorOfListOfOffsetWire.hxx>
26 #include <BRepTopAdaptor_FClass2d.hxx>
27 #include <gp_Pnt2d.hxx>
29 #include <Precision.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Vertex.hxx>
35 #include <TopoDS_Compound.hxx>
36 #include <TopoDS_Wire.hxx>
38 #include <StdFail_NotDone.hxx>
40 //=======================================================================
41 //function : BRepOffsetAPI_MakeOffset
43 //=======================================================================
45 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset()
46 :myIsInitialized( Standard_False)
51 //=======================================================================
52 //function : BRepOffsetAPI_MakeOffset
54 //=======================================================================
56 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine,
57 const GeomAbs_JoinType Join)
63 //=======================================================================
66 //=======================================================================
68 void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face& Spine,
69 const GeomAbs_JoinType Join)
72 myIsInitialized = Standard_True;
75 for (exp.Init(myFace,TopAbs_WIRE); exp.More();exp.Next()) {
76 myWires.Append(exp.Current());
80 //=======================================================================
81 //function : BRepOffsetAPI_MakeOffset
83 //=======================================================================
85 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine,
86 const GeomAbs_JoinType Join)
88 myWires.Append(Spine);
89 myIsInitialized = Standard_True;
93 //=======================================================================
96 //=======================================================================
98 void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join)
103 //=======================================================================
104 //function : BRepOffsetAPI_MakeOffset
106 //=======================================================================
108 void BRepOffsetAPI_MakeOffset::AddWire(const TopoDS_Wire& Spine)
111 myIsInitialized = Standard_True;
112 myWires.Append(Spine);
115 //=======================================================================
116 //function : BuildDomain
118 //=======================================================================
120 static void BuildDomains(TopoDS_Face& myFace,
121 TopTools_ListOfShape& WorkWires,
122 BRepFill_ListOfOffsetWire& myAlgos,
123 GeomAbs_JoinType myJoin,
124 Standard_Boolean isPositive)
126 BRepAlgo_FaceRestrictor FR;
128 TopTools_ListOfShape LOW;
131 if (myFace.IsNull()) {
132 myFace = BRepBuilderAPI_MakeFace(TopoDS::Wire(WorkWires.First()),Standard_True);
134 StdFail_NotDone::Raise ("BRepOffsetAPI_MakeOffset : the wire is not planar");
136 // Modified by Sergey KHROMOV - Thu Apr 26 16:04:43 2001 Begin
137 TopExp_Explorer anExp(myFace, TopAbs_WIRE);
138 TopoDS_Shape aWire1 = WorkWires.First();
141 aWire2 = anExp.Current();
142 if ((aWire1.Orientation() == aWire2.Orientation() && isPositive) ||
143 (aWire1.Orientation() == TopAbs::Complement(aWire2.Orientation()) && !isPositive)) {
144 TopTools_ListOfShape LWires;
145 TopTools_ListIteratorOfListOfShape itl;
146 for (itl.Initialize(WorkWires); itl.More(); itl.Next()) {
147 const TopoDS_Shape& W = itl.Value();
148 LWires.Append(W.Reversed());
153 // Modified by Sergey KHROMOV - Thu Apr 26 16:04:44 2001 End
154 FR.Init(myFace,Standard_True);
155 //====================================================
156 // Construction of faces limited by closed wires.
157 //====================================================
158 TopTools_ListIteratorOfListOfShape itl(WorkWires);
159 for (; itl.More(); itl.Next()) {
160 TopoDS_Wire& W = TopoDS::Wire(itl.Value());
165 TopExp::Vertices (W,VF,VL);
175 StdFail_NotDone::Raise ("BRepOffsetAPI_MakeOffset : Build Domains");
177 TopTools_ListOfShape Faces;
178 for (; FR.More(); FR.Next()) {
179 Faces.Append(FR.Current());
182 //===========================================
183 // No closed wire => only one domain
184 //===========================================
185 if (Faces.IsEmpty()) {
186 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
187 TopoDS_Face F = TopoDS::Face(aLocalShape);
188 // TopoDS_Face F = TopoDS::Face(myFace.EmptyCopied());
189 TopTools_ListIteratorOfListOfShape itW(LOW);
190 for ( ; itW.More(); itW.Next()) {
191 B.Add(F,itW.Value());
193 BRepFill_OffsetWire Algo(F, myJoin);
194 myAlgos.Append(Algo);
198 //====================================================
199 // Classification of open wires.
200 //====================================================
201 // for (TopTools_ListIteratorOfListOfShape itF(Faces); itF.More(); itF.Next()) {
202 TopTools_ListIteratorOfListOfShape itF;
203 for (itF.Initialize(Faces) ; itF.More(); itF.Next()) {
204 TopoDS_Face& F = TopoDS::Face(itF.Value());
205 BRepAdaptor_Surface S(F,0);
206 Standard_Real Tol = BRep_Tool::Tolerance(F);
208 BRepTopAdaptor_FClass2d CL(F,Precision::Confusion());
210 TopTools_ListIteratorOfListOfShape itW(LOW);
212 TopoDS_Wire& W = TopoDS::Wire(itW.Value());
213 //=======================================================
214 // Choice of a point on the wire. + projection on the face.
215 //=======================================================
216 TopExp_Explorer exp(W,TopAbs_VERTEX);
217 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
219 gp_Pnt P3d = BRep_Tool::Pnt(V);
220 Extrema_ExtPS ExtPS (P3d,S,Tol,Tol);
221 Standard_Real Dist2Min = Precision::Infinite();
222 Standard_Real Found = Standard_False;
223 for (Standard_Integer ie = 1; ie <= ExtPS.NbExt(); ie++) {
225 if (ExtPS.SquareDistance(ie) < Dist2Min) {
226 Dist2Min = ExtPS.SquareDistance(ie);
227 Found = Standard_True;
228 ExtPS.Point(ie).Parameter(X,Y);
232 if ( Found && (CL.Perform(PV) == TopAbs_IN)) {
233 // The face that contains a wire is found and it is removed from the list
242 //========================================
243 // Creation of algorithms on each domain.
244 //========================================
245 for (itF.Initialize(Faces); itF.More(); itF.Next()) {
246 BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin);
247 myAlgos.Append(Algo);
251 //=======================================================================
254 //=======================================================================
256 void BRepOffsetAPI_MakeOffset::Perform( const Standard_Real Offset,
257 const Standard_Real Alt)
259 StdFail_NotDone_Raise_if ( !myIsInitialized,
260 "BRepOffsetAPI_MakeOffset : Perform without Init");
264 Standard_Integer i = 1;
265 BRepFill_ListIteratorOfListOfOffsetWire itOW;
268 B.MakeCompound (Res);
269 myLastIsLeft = (Offset <= 0);
273 if( myLeft.IsEmpty() )
275 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 Begin
276 BuildDomains(myFace,myWires,myLeft,myJoin, Standard_False);
277 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 End
280 for (itOW.Initialize(myLeft); itOW.More(); itOW.Next())
282 BRepFill_OffsetWire& Algo = itOW.Value();
283 Algo.Perform(Abs(Offset),Alt);
284 if (Algo.IsDone() && !Algo.Shape().IsNull())
286 B.Add(Res,Algo.Shape());
288 myShape = Algo.Shape();
296 if (myRight.IsEmpty())
298 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:28 2001 Begin
299 BuildDomains(myFace,myWires,myRight,myJoin, Standard_True);
300 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:35 2001 End
303 for(itOW.Initialize(myRight); itOW.More(); itOW.Next())
305 BRepFill_OffsetWire& Algo = itOW.Value();
306 Algo.Perform(Offset,Alt);
308 if (Algo.IsDone() && !Algo.Shape().IsNull())
310 B.Add(Res,Algo.Shape());
313 myShape = Algo.Shape();
328 catch(...) //Every exception was caught.
330 cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
331 Standard_ConstructionError::Caught()->Print(cout);
338 //=======================================================================
341 //=======================================================================
343 void BRepOffsetAPI_MakeOffset::Build()
349 //=======================================================================
350 //function : ShapesFromShape
352 //=======================================================================
354 const TopTools_ListOfShape& BRepOffsetAPI_MakeOffset::Generated
355 (const TopoDS_Shape& S)
358 BRepFill_ListIteratorOfListOfOffsetWire itOW;
359 BRepFill_ListOfOffsetWire* Algos;
364 for (itOW.Initialize(*Algos); itOW.More(); itOW.Next()) {
365 BRepFill_OffsetWire& OW = itOW.Value();
366 TopTools_ListOfShape L;
367 L = OW.GeneratedShapes(S.Oriented(TopAbs_FORWARD));
368 myGenerated.Append(L);
369 L = OW.GeneratedShapes(S.Oriented(TopAbs_REVERSED));
370 myGenerated.Append(L);