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.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepAlgo_FaceRestrictor.hxx>
22 #include <BRepBuilderAPI_MakeFace.hxx>
23 #include <BRepFill_ListIteratorOfListOfOffsetWire.hxx>
24 #include <BRepFill_OffsetWire.hxx>
25 #include <BRepOffsetAPI_MakeOffset.hxx>
26 #include <BRepTopAdaptor_FClass2d.hxx>
27 #include <Extrema_ExtPS.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <Precision.hxx>
31 #include <StdFail_NotDone.hxx>
33 #include <TopExp_Explorer.hxx>
35 #include <TopoDS_Compound.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <BRepTools.hxx>
44 static Standard_Boolean AffichSpine = Standard_False;
47 //=======================================================================
48 //function : BRepOffsetAPI_MakeOffset
50 //=======================================================================
52 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset()
53 : myIsInitialized( Standard_False),
55 myIsOpenResult(Standard_False)
60 //=======================================================================
61 //function : BRepOffsetAPI_MakeOffset
63 //=======================================================================
65 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine,
66 const GeomAbs_JoinType Join,
67 const Standard_Boolean IsOpenResult)
69 Init(Spine, Join, IsOpenResult);
73 //=======================================================================
76 //=======================================================================
78 void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face& Spine,
79 const GeomAbs_JoinType Join,
80 const Standard_Boolean IsOpenResult)
83 myIsInitialized = Standard_True;
85 myIsOpenResult = IsOpenResult;
87 for (exp.Init(myFace,TopAbs_WIRE); exp.More();exp.Next()) {
88 myWires.Append(exp.Current());
92 //=======================================================================
93 //function : BRepOffsetAPI_MakeOffset
95 //=======================================================================
97 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine,
98 const GeomAbs_JoinType Join,
99 const Standard_Boolean IsOpenResult)
101 myWires.Append(Spine);
102 myIsInitialized = Standard_True;
104 myIsOpenResult = IsOpenResult;
107 //=======================================================================
110 //=======================================================================
112 void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join,
113 const Standard_Boolean IsOpenResult)
116 myIsOpenResult = IsOpenResult;
119 //=======================================================================
120 //function : BRepOffsetAPI_MakeOffset
122 //=======================================================================
124 void BRepOffsetAPI_MakeOffset::AddWire(const TopoDS_Wire& Spine)
127 myIsInitialized = Standard_True;
128 myWires.Append(Spine);
131 //=======================================================================
132 //function : BuildDomain
134 //=======================================================================
136 static void BuildDomains(TopoDS_Face& myFace,
137 TopTools_ListOfShape& WorkWires,
138 BRepFill_ListOfOffsetWire& myAlgos,
139 GeomAbs_JoinType myJoin,
140 Standard_Boolean myIsOpenResult,
141 Standard_Boolean isPositive)
143 BRepAlgo_FaceRestrictor FR;
145 TopTools_ListOfShape LOW;
148 if (myFace.IsNull()) {
149 myFace = BRepBuilderAPI_MakeFace(TopoDS::Wire(WorkWires.First()),Standard_True);
151 throw StdFail_NotDone("BRepOffsetAPI_MakeOffset : the wire is not planar");
153 // Modified by Sergey KHROMOV - Thu Apr 26 16:04:43 2001 Begin
154 TopExp_Explorer anExp(myFace, TopAbs_WIRE);
155 TopoDS_Shape aWire1 = WorkWires.First();
158 aWire2 = anExp.Current();
159 if ((aWire1.Orientation() == aWire2.Orientation() && isPositive) ||
160 (aWire1.Orientation() == TopAbs::Complement(aWire2.Orientation()) && !isPositive)) {
161 TopTools_ListOfShape LWires;
162 TopTools_ListIteratorOfListOfShape itl;
163 for (itl.Initialize(WorkWires); itl.More(); itl.Next()) {
164 const TopoDS_Shape& W = itl.Value();
165 LWires.Append(W.Reversed());
170 // Modified by Sergey KHROMOV - Thu Apr 26 16:04:44 2001 End
171 FR.Init(myFace,Standard_True);
172 //====================================================
173 // Construction of faces limited by closed wires.
174 //====================================================
175 TopTools_ListIteratorOfListOfShape itl(WorkWires);
176 for (; itl.More(); itl.Next()) {
177 TopoDS_Wire& W = TopoDS::Wire(itl.Value());
182 TopExp::Vertices (W,VF,VL);
192 throw StdFail_NotDone("BRepOffsetAPI_MakeOffset : Build Domains");
194 TopTools_ListOfShape Faces;
196 Standard_Integer ns = 0;
198 for (; FR.More(); FR.Next()) {
199 Faces.Append(FR.Current());
205 sprintf(name, "FR%d",ns);
206 BRepTools::Write(FR.Current(), name);
211 //===========================================
212 // No closed wire => only one domain
213 //===========================================
214 if (Faces.IsEmpty()) {
215 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
216 TopoDS_Face F = TopoDS::Face(aLocalShape);
217 // TopoDS_Face F = TopoDS::Face(myFace.EmptyCopied());
218 TopTools_ListIteratorOfListOfShape itW(LOW);
219 for ( ; itW.More(); itW.Next()) {
220 B.Add(F,itW.Value());
222 BRepFill_OffsetWire Algo(F, myJoin, myIsOpenResult);
223 myAlgos.Append(Algo);
227 //====================================================
228 // Classification of open wires.
229 //====================================================
230 // for (TopTools_ListIteratorOfListOfShape itF(Faces); itF.More(); itF.Next()) {
231 TopTools_ListIteratorOfListOfShape itF;
232 for (itF.Initialize(Faces) ; itF.More(); itF.Next()) {
233 TopoDS_Face& F = TopoDS::Face(itF.Value());
234 BRepAdaptor_Surface S(F,0);
235 Standard_Real Tol = BRep_Tool::Tolerance(F);
237 BRepTopAdaptor_FClass2d CL(F,Precision::Confusion());
239 TopTools_ListIteratorOfListOfShape itW(LOW);
241 TopoDS_Wire& W = TopoDS::Wire(itW.Value());
242 //=======================================================
243 // Choice of a point on the wire. + projection on the face.
244 //=======================================================
245 TopExp_Explorer exp(W,TopAbs_VERTEX);
246 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
248 gp_Pnt P3d = BRep_Tool::Pnt(V);
249 Extrema_ExtPS ExtPS (P3d,S,Tol,Tol);
250 Standard_Real Dist2Min = Precision::Infinite();
251 Standard_Real Found = Standard_False;
252 for (Standard_Integer ie = 1; ie <= ExtPS.NbExt(); ie++) {
254 if (ExtPS.SquareDistance(ie) < Dist2Min) {
255 Dist2Min = ExtPS.SquareDistance(ie);
256 Found = Standard_True;
257 ExtPS.Point(ie).Parameter(X,Y);
261 if ( Found && (CL.Perform(PV) == TopAbs_IN)) {
262 // The face that contains a wire is found and it is removed from the list
271 //========================================
272 // Creation of algorithms on each domain.
273 //========================================
274 for (itF.Initialize(Faces); itF.More(); itF.Next()) {
275 BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin, myIsOpenResult);
276 myAlgos.Append(Algo);
280 //=======================================================================
283 //=======================================================================
285 void BRepOffsetAPI_MakeOffset::Perform(const Standard_Real Offset,
286 const Standard_Real Alt)
288 StdFail_NotDone_Raise_if ( !myIsInitialized,
289 "BRepOffsetAPI_MakeOffset : Perform without Init");
293 Standard_Integer i = 1;
294 BRepFill_ListIteratorOfListOfOffsetWire itOW;
297 B.MakeCompound (Res);
298 myLastIsLeft = (Offset <= 0);
302 if( myLeft.IsEmpty() )
304 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 Begin
305 BuildDomains(myFace,myWires,myLeft,myJoin,myIsOpenResult, Standard_False);
306 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 End
309 for (itOW.Initialize(myLeft); itOW.More(); itOW.Next())
311 BRepFill_OffsetWire& Algo = itOW.Value();
312 Algo.Perform(Abs(Offset),Alt);
313 if (Algo.IsDone() && !Algo.Shape().IsNull())
315 B.Add(Res,Algo.Shape());
317 myShape = Algo.Shape();
325 if (myRight.IsEmpty())
327 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:28 2001 Begin
328 BuildDomains(myFace,myWires,myRight,myJoin,myIsOpenResult, Standard_True);
329 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:35 2001 End
332 for(itOW.Initialize(myRight); itOW.More(); itOW.Next())
334 BRepFill_OffsetWire& Algo = itOW.Value();
335 Algo.Perform(Offset,Alt);
337 if (Algo.IsDone() && !Algo.Shape().IsNull())
339 B.Add(Res,Algo.Shape());
342 myShape = Algo.Shape();
357 catch(Standard_Failure const& anException) {
359 std::cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
360 anException.Print(std::cout);
361 std::cout<<std::endl;
369 //=======================================================================
372 //=======================================================================
374 void BRepOffsetAPI_MakeOffset::Build()
380 //=======================================================================
381 //function : ShapesFromShape
383 //=======================================================================
385 const TopTools_ListOfShape& BRepOffsetAPI_MakeOffset::Generated
386 (const TopoDS_Shape& S)
389 BRepFill_ListIteratorOfListOfOffsetWire itOW;
390 BRepFill_ListOfOffsetWire* Algos;
395 for (itOW.Initialize(*Algos); itOW.More(); itOW.Next()) {
396 BRepFill_OffsetWire& OW = itOW.Value();
397 TopTools_ListOfShape L;
398 L = OW.GeneratedShapes(S.Oriented(TopAbs_FORWARD));
399 myGenerated.Append(L);
400 L = OW.GeneratedShapes(S.Oriented(TopAbs_REVERSED));
401 myGenerated.Append(L);