0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_MakeOffset.cxx
CommitLineData
b311480e 1// Created on: 1995-09-18
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
42cf5bc1 17
7fd59977 18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
7fd59977 20#include <BRepAdaptor_Surface.hxx>
42cf5bc1 21#include <BRepAlgo_FaceRestrictor.hxx>
22#include <BRepBuilderAPI_MakeFace.hxx>
7fd59977 23#include <BRepFill_ListIteratorOfListOfOffsetWire.hxx>
42cf5bc1 24#include <BRepFill_OffsetWire.hxx>
25#include <BRepOffsetAPI_MakeOffset.hxx>
7fd59977 26#include <BRepTopAdaptor_FClass2d.hxx>
42cf5bc1 27#include <Extrema_ExtPS.hxx>
7fd59977 28#include <gp_Pnt.hxx>
42cf5bc1 29#include <gp_Pnt2d.hxx>
7fd59977 30#include <Precision.hxx>
42cf5bc1 31#include <StdFail_NotDone.hxx>
7fd59977 32#include <TopExp.hxx>
42cf5bc1 33#include <TopExp_Explorer.hxx>
7fd59977 34#include <TopoDS.hxx>
7fd59977 35#include <TopoDS_Compound.hxx>
42cf5bc1 36#include <TopoDS_Face.hxx>
37#include <TopoDS_Shape.hxx>
38#include <TopoDS_Vertex.hxx>
7fd59977 39#include <TopoDS_Wire.hxx>
42cf5bc1 40#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 41
873c119f 42#ifdef OCCT_DEBUG
43#include <BRepTools.hxx>
44static Standard_Boolean AffichSpine = Standard_False;
45#endif
7fd59977 46
47//=======================================================================
48//function : BRepOffsetAPI_MakeOffset
49//purpose :
50//=======================================================================
51
52BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset()
75d1222c 53 : myIsInitialized( Standard_False),
54 myJoin(GeomAbs_Arc),
55 myIsOpenResult(Standard_False)
7fd59977 56{
57}
58
59
60//=======================================================================
61//function : BRepOffsetAPI_MakeOffset
62//purpose :
63//=======================================================================
64
65BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine,
6a442250 66 const GeomAbs_JoinType Join,
67 const Standard_Boolean IsOpenResult)
7fd59977 68{
6a442250 69 Init(Spine, Join, IsOpenResult);
7fd59977 70}
71
72
73//=======================================================================
74//function : Init
75//purpose :
76//=======================================================================
77
78void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face& Spine,
6a442250 79 const GeomAbs_JoinType Join,
80 const Standard_Boolean IsOpenResult)
7fd59977 81{
82 myFace = Spine;
83 myIsInitialized = Standard_True;
84 myJoin = Join;
6a442250 85 myIsOpenResult = IsOpenResult;
7fd59977 86 TopExp_Explorer exp;
87 for (exp.Init(myFace,TopAbs_WIRE); exp.More();exp.Next()) {
88 myWires.Append(exp.Current());
89 }
90}
91
92//=======================================================================
93//function : BRepOffsetAPI_MakeOffset
94//purpose :
95//=======================================================================
96
97BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine,
6a442250 98 const GeomAbs_JoinType Join,
99 const Standard_Boolean IsOpenResult)
7fd59977 100{
101 myWires.Append(Spine);
102 myIsInitialized = Standard_True;
103 myJoin = Join;
6a442250 104 myIsOpenResult = IsOpenResult;
7fd59977 105}
106
107//=======================================================================
108//function : Init
109//purpose :
110//=======================================================================
111
6a442250 112void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join,
113 const Standard_Boolean IsOpenResult)
7fd59977 114{
115 myJoin = Join;
6a442250 116 myIsOpenResult = IsOpenResult;
7fd59977 117}
73cd8a8a 118
7fd59977 119//=======================================================================
120//function : BRepOffsetAPI_MakeOffset
121//purpose :
122//=======================================================================
123
124void BRepOffsetAPI_MakeOffset::AddWire(const TopoDS_Wire& Spine)
73cd8a8a 125
7fd59977 126{
127 myIsInitialized = Standard_True;
128 myWires.Append(Spine);
129}
130
131//=======================================================================
132//function : BuildDomain
133//purpose :
134//=======================================================================
135
136static void BuildDomains(TopoDS_Face& myFace,
6a442250 137 TopTools_ListOfShape& WorkWires,
138 BRepFill_ListOfOffsetWire& myAlgos,
139 GeomAbs_JoinType myJoin,
140 Standard_Boolean myIsOpenResult,
141 Standard_Boolean isPositive)
7fd59977 142{
143 BRepAlgo_FaceRestrictor FR;
144 TopoDS_Vertex VF,VL;
145 TopTools_ListOfShape LOW;
146 BRep_Builder B;
147
148 if (myFace.IsNull()) {
149 myFace = BRepBuilderAPI_MakeFace(TopoDS::Wire(WorkWires.First()),Standard_True);
150 if (myFace.IsNull())
151 StdFail_NotDone::Raise ("BRepOffsetAPI_MakeOffset : the wire is not planar");
152 }
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();
156 TopoDS_Shape aWire2;
157 if (anExp.More()) {
158 aWire2 = anExp.Current();
159 if ((aWire1.Orientation() == aWire2.Orientation() && isPositive) ||
73cd8a8a 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());
166 }
167 WorkWires = LWires;
7fd59977 168 }
169 }
170// Modified by Sergey KHROMOV - Thu Apr 26 16:04:44 2001 End
171 FR.Init(myFace,Standard_True);
172 //====================================================
0d969553 173 // Construction of faces limited by closed wires.
7fd59977 174 //====================================================
175 TopTools_ListIteratorOfListOfShape itl(WorkWires);
176 for (; itl.More(); itl.Next()) {
177 TopoDS_Wire& W = TopoDS::Wire(itl.Value());
178 if (W.Closed()){
179 FR.Add(W);
180 continue;
181 }
182 TopExp::Vertices (W,VF,VL);
183 if (VF.IsSame(VL)) {
184 FR.Add(W);
185 }
186 else {
187 LOW.Append(W);
188 }
189 }
190 FR.Perform();
191 if (!FR.IsDone()) {
192 StdFail_NotDone::Raise ("BRepOffsetAPI_MakeOffset : Build Domains");
193 }
194 TopTools_ListOfShape Faces;
873c119f 195#ifdef OCCT_DEBUG
196 Standard_Integer ns = 0;
197#endif
7fd59977 198 for (; FR.More(); FR.Next()) {
199 Faces.Append(FR.Current());
873c119f 200#ifdef OCCT_DEBUG
201 if(AffichSpine)
202 {
203 char name[32];
204 ns++;
205 sprintf(name, "FR%d",ns);
206 BRepTools::Write(FR.Current(), name);
207 }
208#endif
7fd59977 209 }
210
211 //===========================================
0d969553 212 // No closed wire => only one domain
7fd59977 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());
221 }
6a442250 222 BRepFill_OffsetWire Algo(F, myJoin, myIsOpenResult);
7fd59977 223 myAlgos.Append(Algo);
224 return;
225 }
73cd8a8a 226
7fd59977 227 //====================================================
0d969553 228 // Classification of open wires.
7fd59977 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);
236
237 BRepTopAdaptor_FClass2d CL(F,Precision::Confusion());
238
239 TopTools_ListIteratorOfListOfShape itW(LOW);
240 while (itW.More()) {
241 TopoDS_Wire& W = TopoDS::Wire(itW.Value());
242 //=======================================================
0d969553 243 // Choice of a point on the wire. + projection on the face.
7fd59977 244 //=======================================================
245 TopExp_Explorer exp(W,TopAbs_VERTEX);
246 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
247 gp_Pnt2d PV;
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++) {
73cd8a8a 253 Standard_Real X,Y;
254 if (ExtPS.SquareDistance(ie) < Dist2Min) {
255 Dist2Min = ExtPS.SquareDistance(ie);
256 Found = Standard_True;
257 ExtPS.Point(ie).Parameter(X,Y);
258 PV.SetCoord(X,Y);
259 }
7fd59977 260 }
261 if ( Found && (CL.Perform(PV) == TopAbs_IN)) {
73cd8a8a 262 // The face that contains a wire is found and it is removed from the list
263 B.Add(F,W);
264 LOW.Remove(itW);
7fd59977 265 }
266 else {
73cd8a8a 267 itW.Next();
7fd59977 268 }
269 }
270 }
271 //========================================
0d969553 272 // Creation of algorithms on each domain.
7fd59977 273 //========================================
274 for (itF.Initialize(Faces); itF.More(); itF.Next()) {
6a442250 275 BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin, myIsOpenResult);
7fd59977 276 myAlgos.Append(Algo);
277 }
278}
279
280//=======================================================================
281//function : Perform
282//purpose :
283//=======================================================================
284
6a442250 285void BRepOffsetAPI_MakeOffset::Perform(const Standard_Real Offset,
286 const Standard_Real Alt)
73cd8a8a 287{
7fd59977 288 StdFail_NotDone_Raise_if ( !myIsInitialized,
73cd8a8a 289 "BRepOffsetAPI_MakeOffset : Perform without Init");
7fd59977 290
ab87e6fc 291 try
73cd8a8a 292 {
ab87e6fc 293 Standard_Integer i = 1;
294 BRepFill_ListIteratorOfListOfOffsetWire itOW;
295 TopoDS_Compound Res;
296 BRep_Builder B;
297 B.MakeCompound (Res);
298 myLastIsLeft = (Offset <= 0);
73cd8a8a 299
ab87e6fc 300 if( Offset <= 0. )
73cd8a8a 301 {
ab87e6fc 302 if( myLeft.IsEmpty() )
73cd8a8a 303 {
ab87e6fc 304 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 Begin
6a442250 305 BuildDomains(myFace,myWires,myLeft,myJoin,myIsOpenResult, Standard_False);
ab87e6fc 306 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 End
73cd8a8a 307 }
7fd59977 308
ab87e6fc 309 for (itOW.Initialize(myLeft); itOW.More(); itOW.Next())
73cd8a8a 310 {
ab87e6fc 311 BRepFill_OffsetWire& Algo = itOW.Value();
312 Algo.Perform(Abs(Offset),Alt);
313 if (Algo.IsDone() && !Algo.Shape().IsNull())
73cd8a8a 314 {
ab87e6fc 315 B.Add(Res,Algo.Shape());
316 if (i == 1)
317 myShape = Algo.Shape();
318
319 i++;
ab87e6fc 320 }
7fd59977 321 }
73cd8a8a 322 }
ab87e6fc 323 else
73cd8a8a 324 {
ab87e6fc 325 if (myRight.IsEmpty())
73cd8a8a 326 {
ab87e6fc 327 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:28 2001 Begin
6a442250 328 BuildDomains(myFace,myWires,myRight,myJoin,myIsOpenResult, Standard_True);
ab87e6fc 329 // Modified by Sergey KHROMOV - Fri Apr 27 14:35:35 2001 End
73cd8a8a 330 }
ab87e6fc 331
332 for(itOW.Initialize(myRight); itOW.More(); itOW.Next())
73cd8a8a 333 {
ab87e6fc 334 BRepFill_OffsetWire& Algo = itOW.Value();
335 Algo.Perform(Offset,Alt);
73cd8a8a 336
ab87e6fc 337 if (Algo.IsDone() && !Algo.Shape().IsNull())
73cd8a8a 338 {
ab87e6fc 339 B.Add(Res,Algo.Shape());
340
341 if (i == 1)
342 myShape = Algo.Shape();
343
344 i++;
ab87e6fc 345 }
7fd59977 346 }
73cd8a8a 347 }
ab87e6fc 348
349 if( i > 2 )
350 myShape = Res;
351
352 if(myShape.IsNull())
353 NotDone();
354 else
355 Done();
73cd8a8a 356 }
b350f6ee 357 catch(Standard_Failure) //Every exception was caught.
73cd8a8a 358 {
0797d9d3 359#ifdef OCCT_DEBUG
ab87e6fc 360 cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
361 Standard_ConstructionError::Caught()->Print(cout);
362 cout<<endl;
63c629aa 363#endif
ab87e6fc 364 NotDone();
365 myShape.Nullify();
7fd59977 366 }
73cd8a8a 367}
7fd59977 368
369//=======================================================================
370//function : Build
371//purpose :
372//=======================================================================
373
374void BRepOffsetAPI_MakeOffset::Build()
375{
376 Done();
377}
378
379
380//=======================================================================
381//function : ShapesFromShape
382//purpose :
383//=======================================================================
384
385const TopTools_ListOfShape& BRepOffsetAPI_MakeOffset::Generated
73cd8a8a 386 (const TopoDS_Shape& S)
7fd59977 387{
388 myGenerated.Clear();
389 BRepFill_ListIteratorOfListOfOffsetWire itOW;
390 BRepFill_ListOfOffsetWire* Algos;
391 Algos= &myLeft;
392 if (!myLastIsLeft) {
393 Algos = &myRight;
394 }
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);
402 }
403 return myGenerated;
404}