0028501: Incomplete result of offset operation in mode Complete with Join type inters...
[occt.git] / src / BRepFeat / BRepFeat_MakePrism.cxx
CommitLineData
b311480e 1// Created on: 1996-02-13
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1996-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
7fd59977 17
42cf5bc1 18#include <Bnd_Box.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepAlgoAPI_Cut.hxx>
21#include <BRepAlgoAPI_Fuse.hxx>
22#include <BRepBndLib.hxx>
23#include <BRepBuilderAPI.hxx>
7fd59977 24#include <BRepFeat.hxx>
42cf5bc1 25#include <BRepFeat_MakePrism.hxx>
26#include <BRepLib_MakeFace.hxx>
27#include <BRepPrimAPI_MakeBox.hxx>
28#include <BRepTools.hxx>
7fd59977 29#include <Geom_Curve.hxx>
30#include <Geom_Line.hxx>
42cf5bc1 31#include <Geom_Plane.hxx>
7fd59977 32#include <Geom_RectangularTrimmedSurface.hxx>
33#include <Geom_Surface.hxx>
42cf5bc1 34#include <gp_Ax1.hxx>
35#include <gp_Dir.hxx>
36#include <gp_Pln.hxx>
37#include <gp_Pnt.hxx>
38#include <gp_Pnt2d.hxx>
39#include <gp_Vec.hxx>
40#include <LocOpe.hxx>
41#include <LocOpe_CSIntersector.hxx>
42#include <LocOpe_PntFace.hxx>
43#include <LocOpe_Prism.hxx>
44#include <Precision.hxx>
45#include <Standard_ConstructionError.hxx>
7fd59977 46#include <TColGeom_SequenceOfCurve.hxx>
42cf5bc1 47#include <TColgp_SequenceOfPnt.hxx>
48#include <TopExp.hxx>
7fd59977 49#include <TopExp_Explorer.hxx>
42cf5bc1 50#include <TopoDS.hxx>
51#include <TopoDS_Compound.hxx>
52#include <TopoDS_Edge.hxx>
53#include <TopoDS_Face.hxx>
54#include <TopoDS_Shape.hxx>
55#include <TopoDS_Solid.hxx>
7fd59977 56#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
42cf5bc1 57#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
7fd59977 58#include <TopTools_ListIteratorOfListOfShape.hxx>
59#include <TopTools_ListOfShape.hxx>
42cf5bc1 60#include <TopTools_MapOfShape.hxx>
7fd59977 61
0797d9d3 62#ifdef OCCT_DEBUG
1d0a9d4d 63extern Standard_Boolean BRepFeat_GettraceFEAT();
7fd59977 64#endif
65
66static void MajMap(const TopoDS_Shape&, // base
67 const LocOpe_Prism&,
68 TopTools_DataMapOfShapeListOfShape&, // myMap
69 TopoDS_Shape&, // myFShape
70 TopoDS_Shape&); // myLShape
71
72static Standard_Boolean ToFuse(const TopoDS_Face& ,
73 const TopoDS_Face&);
74
7fd59977 75static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
76 const TopoDS_Face& theSkface,
77 const TopoDS_Shape& theSFrom,
78 const TopoDS_Shape& theSUntil);
79
80static Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
81 const TopoDS_Shape& Until);
82
83static Handle(Geom_Curve) TestCurve(const TopoDS_Shape&,
84 const gp_Vec&);
85
86
87//=======================================================================
88//function : Init
89//purpose :
90//=======================================================================
91
92void BRepFeat_MakePrism::Init(const TopoDS_Shape& Sbase,
93 const TopoDS_Shape& Pbase,
94 const TopoDS_Face& Skface,
95 const gp_Dir& Direc,
96 const Standard_Integer Mode,
97 const Standard_Boolean Modify)
98{
0797d9d3 99#ifdef OCCT_DEBUG
7fd59977 100 Standard_Boolean trc = BRepFeat_GettraceFEAT();
101 if (trc) cout << "BRepFeat_MakePrism::Init" << endl;
102#endif
103 mySkface = Skface;
104 SketchFaceValid();
105 mySbase = Sbase;
106 BasisShapeValid();
107 myPbase = Pbase;
108 mySlface.Clear();
109 myDir = Direc;
110 if(Mode == 0) {
111 myFuse = Standard_False;
112 myJustFeat = Standard_False;
113 }
114 else if(Mode == 1) {
115 myFuse = Standard_True;
116 myJustFeat = Standard_False;
117 }
118 else if(Mode == 2) {
119 myFuse = Standard_True;
120 myJustFeat = Standard_True;
121 }
122 else {
123 }
124 myModify = Modify;
125 myJustGluer = Standard_False;
126
127
128 //-------------- ifv
129 //mySkface.Nullify();
130 //-------------- ifv
131
132
133 myShape.Nullify();
134 myNewEdges.Clear();
135 myTgtEdges.Clear();
136 myMap.Clear();
137 myFShape.Nullify();
138 myLShape.Nullify();
139 TopExp_Explorer exp;
140 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
141 TopTools_ListOfShape thelist;
142 myMap.Bind(exp.Current(), thelist);
143 myMap(exp.Current()).Append(exp.Current());
144 }
0797d9d3 145#ifdef OCCT_DEBUG
7fd59977 146 if (trc) {
147 if (myJustFeat) cout << " Just Feature" << endl;
148 if (myFuse) cout << " Fuse" << endl;
149 if (!myFuse) cout << " Cut" << endl;
150 if (!myModify) cout << " Modify = 0" << endl;
151 }
152#endif
153}
154
155
156//=======================================================================
157//function : Add
0d969553 158//purpose : add elements of sliding (edge on face)
7fd59977 159//=======================================================================
160
161void BRepFeat_MakePrism::Add(const TopoDS_Edge& E,
162 const TopoDS_Face& F)
163{
0797d9d3 164#ifdef OCCT_DEBUG
7fd59977 165 Standard_Boolean trc = BRepFeat_GettraceFEAT();
166 if (trc) cout << "BRepFeat_MakePrism::Add(Edge,face)" << endl;
167#endif
168 TopExp_Explorer exp;
169 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
170 if (exp.Current().IsSame(F)) {
171 break;
172 }
173 }
174 if (!exp.More()) {
9775fa61 175 throw Standard_ConstructionError();
7fd59977 176 }
177
178 for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
179 if (exp.Current().IsSame(E)) {
180 break;
181 }
182 }
183 if (!exp.More()) {
9775fa61 184 throw Standard_ConstructionError();
7fd59977 185 }
186
187 if (!mySlface.IsBound(F)) {
188 TopTools_ListOfShape thelist1;
189 mySlface.Bind(F, thelist1);
190 }
191 TopTools_ListIteratorOfListOfShape itl(mySlface(F));
192 for (; itl.More();itl.Next()) {
193 if (itl.Value().IsSame(E)) {
194 break;
195 }
196 }
197 if (!itl.More()) {
198 mySlface(F).Append(E);
199 }
200}
201
202
203//=======================================================================
204//function : Perform
0d969553
Y
205//purpose : construction of prism of length Length and
206// call of reconstruction topo
7fd59977 207//=======================================================================
208
209void BRepFeat_MakePrism::Perform(const Standard_Real Length)
210{
0797d9d3 211#ifdef OCCT_DEBUG
7fd59977 212 Standard_Boolean trc = BRepFeat_GettraceFEAT();
213 if (trc) cout << "BRepFeat_MakePrism::Perform(Length)" << endl;
214#endif
215 mySFrom.Nullify();
216 ShapeFromValid();
217 mySUntil.Nullify();
218 ShapeUntilValid();
219 myGluedF.Clear();
220 myPerfSelection = BRepFeat_NoSelection;
221 PerfSelectionValid();
222 gp_Vec V(Length*myDir);
223
0d969553 224//construction of prism of height Length
7fd59977 225
226 LocOpe_Prism thePrism(myPbase,V);
227 TopoDS_Shape VraiPrism = thePrism.Shape();
228
0d969553 229// management of descendants
7fd59977 230 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
231
232
0d969553 233 myGShape = VraiPrism; // the primitive
7fd59977 234 GeneratedShapeValid();
235
236 TopoDS_Face FFace;
237
238 Standard_Boolean found = Standard_False;
239
0d969553
Y
240// try to detect the faces of gluing
241// in case if the top of the prism is tangent to the initial shape
7fd59977 242
243 if(!mySkface.IsNull() || !mySlface.IsEmpty()) {
244 if(myLShape.ShapeType() == TopAbs_WIRE) {
245 TopExp_Explorer ex1(VraiPrism, TopAbs_FACE);
246 for(; ex1.More(); ex1.Next()) {
d7988ee1 247 TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE);
248 for(; ex2.More(); ex2.Next()) {
249 if(ex2.Current().IsSame(myLShape)) {
250 FFace = TopoDS::Face(ex1.Current());
251 found = Standard_True;
252 break;
253 }
254 }
255 if(found) break;
7fd59977 256 }
257 }
258
259 TopExp_Explorer exp(mySbase, TopAbs_FACE);
260 for(; exp.More(); exp.Next()) {
261 const TopoDS_Face& ff = TopoDS::Face(exp.Current());
262 if(ToFuse(ff, FFace)) {
d7988ee1 263 TopTools_DataMapOfShapeListOfShape sl;
264 if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace))
265 break;
7fd59977 266 }
267 }
268 }
269
0d969553 270// management of faces of gluing given by the user
7fd59977 271
7fd59977 272 GluedFacesValid();
7fd59977 273
0d969553 274 if(!myGluedF.IsEmpty()) { // case gluing
7fd59977 275 myJustGluer = Standard_True;
276 thePrism.Curves(myCurves);
277 myBCurve = thePrism.BarycCurve();
0d969553 278 GlobalPerform(); // topological reconstruction
7fd59977 279 }
280
0d969553 281// if there is no gluing -> call of ope topo
7fd59977 282 if(!myJustGluer) {
283 if(myFuse == 1 && !myJustFeat) {
7fd59977 284 BRepAlgoAPI_Fuse f(mySbase, myGShape);
285 myShape = f.Shape();
286 UpdateDescendants(f, myShape, Standard_False);
7fd59977 287 Done();
288 }
289 else if(myFuse == 0) {
7fd59977 290 BRepAlgoAPI_Cut c(mySbase, myGShape);
291 myShape = c.Shape();
292 UpdateDescendants(c, myShape, Standard_False);
7fd59977 293 Done();
294 }
295 else {
296 myShape = myGShape;
297 Done();
298 }
299 }
300}
301
302
303//=======================================================================
304//function : Perform
0d969553
Y
305//purpose : construction of prism oriented at the face Until, sufficiently
306// long; call of topological reconstruction
7fd59977 307//=======================================================================
308
309void BRepFeat_MakePrism::Perform(const TopoDS_Shape& Until)
310{
0797d9d3 311#ifdef OCCT_DEBUG
7fd59977 312 Standard_Boolean trc = BRepFeat_GettraceFEAT();
313 if (trc) cout << "BRepFeat_MakePrism::Perform(Until)" << endl;
314#endif
315 if (Until.IsNull()) {
9775fa61 316 throw Standard_ConstructionError();
7fd59977 317 }
318 TopExp_Explorer exp(Until, TopAbs_FACE);
319 if (!exp.More()) {
9775fa61 320 throw Standard_ConstructionError();
7fd59977 321 }
322 myGluedF.Clear();
323 myPerfSelection = BRepFeat_SelectionU;
324 PerfSelectionValid();
325 mySFrom.Nullify();
326 ShapeFromValid();
327 mySUntil = Until;
328 Standard_Boolean Trf = TransformShapeFU(1);
329 ShapeUntilValid();
330 Handle(Geom_Curve) C = TestCurve(myPbase,myDir);
331 Standard_Integer sens = SensOfPrism(C, mySUntil);
332 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
333 gp_Vec V(2*sens*Height*myDir);
334
0d969553 335// construction of long prism
7fd59977 336 LocOpe_Prism thePrism(myPbase,V);
337 TopoDS_Shape VraiPrism = thePrism.Shape();
338
0d969553 339// in case of support of face Until
7fd59977 340 if(!Trf) {
341 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
342 myGShape = VraiPrism;
343 GeneratedShapeValid();
7fd59977 344 GluedFacesValid();
7fd59977 345 thePrism.Curves(myCurves);
346 myBCurve = thePrism.BarycCurve();
347 GlobalPerform();
348 }
0d969553 349 else { // until support -> passage to topological operations
7fd59977 350 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
351 TColGeom_SequenceOfCurve scur;
352 scur.Clear();
353 scur.Append(C);
354
0d969553 355// direction of the prism depending on Until
7fd59977 356
357 LocOpe_CSIntersector ASI(mySUntil);
358 ASI.Perform(scur);
359 TopAbs_Orientation Or;
360 if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
361 if (myFuse == 1) {
093a3fe5 362 Or = ASI.Point(1, 1).Orientation();
7fd59977 363 }
364 else {
093a3fe5 365 Or = ASI.Point(1, ASI.NbPoints(1)).Orientation();
7fd59977 366 }
367 if(sens==-1) Or=TopAbs::Reverse(Or);
368 TopoDS_Face FUntil = ASI.Point(1,1).Face();
369 TopoDS_Shape Comp;
370 BRep_Builder B;
371 B.MakeCompound(TopoDS::Compound(Comp));
372 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
373 if (!S.IsNull()) B.Add(Comp,S);
7fd59977 374 BRepAlgoAPI_Cut trP(VraiPrism,Comp);
375 UpdateDescendants(trP, trP.Shape(), Standard_False);
093a3fe5 376 //
7fd59977 377 TopExp_Explorer ex(trP.Shape(), TopAbs_SOLID);
378 TopoDS_Shape Cutsh = ex.Current();
093a3fe5 379 if (myFuse == 1 && !myJustFeat) {
380 BRepAlgoAPI_Fuse f(mySbase, Cutsh);
381 myShape = f.Shape();
382 UpdateDescendants(f, myShape, Standard_False);
383 Done();
7fd59977 384 }
385 else if(myFuse == 0) {
093a3fe5 386 BRepAlgoAPI_Cut c(mySbase, Cutsh);
387 myShape = c.Shape();
388 UpdateDescendants(c, myShape, Standard_False);
389 Done();
7fd59977 390 }
391 else {
093a3fe5 392 myShape = Cutsh;
393 Done();
7fd59977 394 }
7fd59977 395 }
396 }
7fd59977 397}
398
7fd59977 399//=======================================================================
400//function : Perform
0d969553
Y
401//purpose : construction of a sufficiently long and properly oriented prism
402// call of topological reconstruction
7fd59977 403//=======================================================================
404
405void BRepFeat_MakePrism::Perform(const TopoDS_Shape& From,
406 const TopoDS_Shape& Until)
407{
0797d9d3 408#ifdef OCCT_DEBUG
7fd59977 409 Standard_Boolean trc = BRepFeat_GettraceFEAT();
410 if (trc) cout << "BRepFeat_MakePrism::Perform(From,Until)" << endl;
411#endif
412 if (From.IsNull() || Until.IsNull()) {
9775fa61 413 throw Standard_ConstructionError();
7fd59977 414 }
415
416 if (!mySkface.IsNull()) {
417 if (From.IsSame(mySkface)) {
418 myJustGluer = Standard_True;
419 Perform(Until);
420 if (myJustGluer) return;
421 }
422 else if (Until.IsSame(mySkface)) {
423 myJustGluer = Standard_True;
424 Perform(From);
425 if (myJustGluer) return;
426 }
427 }
428
429 myGluedF.Clear();
430 myPerfSelection = BRepFeat_SelectionFU;
431 PerfSelectionValid();
432
433 TopExp_Explorer exp(From, TopAbs_FACE);
434 if (!exp.More()) {
9775fa61 435 throw Standard_ConstructionError();
7fd59977 436 }
437 exp.Init(Until, TopAbs_FACE);
438 if (!exp.More()) {
9775fa61 439 throw Standard_ConstructionError();
7fd59977 440 }
441 mySFrom = From;
442 Standard_Boolean Trff = TransformShapeFU(0);
443 ShapeFromValid();
444 mySUntil = Until;
445 Standard_Boolean Trfu = TransformShapeFU(1);
446 ShapeUntilValid();
447 if(Trfu != Trff) {
448 NotDone();
449 myStatusError = BRepFeat_IncTypes;
450 return;
451 }
452
0d969553 453// length depending on bounding boxes
7fd59977 454
455 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
456 Handle(Geom_Curve) C = TestCurve(myPbase,myDir);
0d969553
Y
457 Standard_Integer sens; // direction of prism
458 Standard_Integer tran; // transfer of prism
7fd59977 459 if(From.IsSame(Until)) {
460 sens = 1;
461 tran = -1;
462 }
463 else {
464 sens = SensOfPrism(C, mySUntil);
465 tran = sens*SensOfPrism(C, mySFrom);
466 }
467 LocOpe_Prism thePrism;
468 if(tran < 0) {
469 gp_Vec Vtra(-3*Height*sens/2.*myDir);
470 thePrism.Perform(myPbase,3*sens*Height*myDir,Vtra);
471 }
472 else {
473 thePrism.Perform(myPbase,2*sens*Height*myDir);
474 }
475 TopoDS_Shape VraiPrism = thePrism.Shape();
476
477 if(!Trff) {
478 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
479
480 myGShape = VraiPrism;
481 GeneratedShapeValid();
7fd59977 482 GluedFacesValid();
7fd59977 483 thePrism.Curves(myCurves);
484 myBCurve = thePrism.BarycCurve();
485 GlobalPerform();
486 }
0d969553 487 else { // case until support -> topological operation
7fd59977 488 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
489 TColGeom_SequenceOfCurve scur;
490 scur.Clear();
491 scur.Append(C);
492 LocOpe_CSIntersector ASI1(mySUntil);
493 LocOpe_CSIntersector ASI2(mySFrom);
494 ASI1.Perform(scur);
495 ASI2.Perform(scur);
496 TopAbs_Orientation OrU, OrF;
497 TopoDS_Face FFrom, FUntil;
d7988ee1 498 Standard_Real ParF, ParU;
7fd59977 499 if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
500 if (myFuse == 1) {
d7988ee1 501 OrU = ASI1.Point(1,1).Orientation();
7fd59977 502 }
503 else {
d7988ee1 504 OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation();
7fd59977 505 }
506 if(sens==-1) OrU = TopAbs::Reverse(OrU);
507 FUntil = ASI1.Point(1,1).Face();
d7988ee1 508 ParU = ASI1.Point(1,1).Parameter();
7fd59977 509 }
510 else {
511 NotDone();
512 myStatusError = BRepFeat_NoIntersectU;
513 return;
514 }
515 if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
516 OrF = ASI2.Point(1,1).Orientation();
517 if(sens==1) OrF = TopAbs::Reverse(OrF);
518 FFrom = ASI2.Point(1,1).Face();
d7988ee1 519 ParF = ASI2.Point(1,1).Parameter();
7fd59977 520 }
521 else {
522 NotDone();
523 myStatusError = BRepFeat_NoIntersectF;
524 return;
525 }
d7988ee1 526 if(tran > 0 && (Abs(ParU) < Abs(ParF)))
527 {
528 TopAbs_Orientation Or;
529 Or = OrU;
530 OrU = OrF;
531 OrF = Or;
532 }
093a3fe5 533 //
534 TopTools_ListOfShape aLTools;
7fd59977 535 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, OrU);
536 if (!S.IsNull()) {
093a3fe5 537 aLTools.Append(S);
7fd59977 538 }
539 else {
540 NotDone();
541 myStatusError = BRepFeat_NullToolU;
542 return;
543 }
544 TopoDS_Solid SS = BRepFeat::Tool(mySFrom, FFrom, OrF);
545 if (!SS.IsNull()) {
093a3fe5 546 aLTools.Append(SS);
7fd59977 547 }
548 else {
549 NotDone();
550 myStatusError = BRepFeat_NullToolF;
551 return;
552 }
093a3fe5 553 //
554 TopTools_ListOfShape aLObj;
555 aLObj.Append(VraiPrism);
556 //
557 BRepAlgoAPI_Cut trP;
558 trP.SetArguments(aLObj);
559 trP.SetTools(aLTools);
560 trP.Build();
7fd59977 561 UpdateDescendants(trP, trP.Shape(), Standard_False);
7fd59977 562 if(myFuse == 1 && !myJustFeat) {
7fd59977 563 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
564 myShape = f.Shape();
565 UpdateDescendants(f, myShape, Standard_False);
7fd59977 566 Done();
567 }
568 else if(myFuse == 0) {
7fd59977 569 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
570 myShape = c.Shape();
571 UpdateDescendants(c, myShape, Standard_False);
7fd59977 572 Done();
573 }
574 else {
575 myShape = trP.Shape();
093a3fe5 576 Done();
7fd59977 577 }
578 }
7fd59977 579}
580
7fd59977 581//=======================================================================
582//function : PerformUntilEnd
0d969553 583//purpose : construction of a prism and reconstruction
7fd59977 584//=======================================================================
585
586void BRepFeat_MakePrism::PerformUntilEnd()
587{
0797d9d3 588#ifdef OCCT_DEBUG
7fd59977 589 Standard_Boolean trc = BRepFeat_GettraceFEAT();
590 if (trc) cout << "BRepFeat_MakePrism::PerformUntilEnd()" << endl;
591#endif
592 myPerfSelection = BRepFeat_SelectionSh;
593 PerfSelectionValid();
594 myGluedF.Clear();
595 mySUntil.Nullify();
596 ShapeUntilValid();
597 mySFrom.Nullify();
598 ShapeFromValid();
599 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
600 gp_Vec V(2*Height*myDir);
601
602 LocOpe_Prism thePrism(myPbase,V);
603 TopoDS_Shape VraiPrism = thePrism.Shape();
604
605 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
606
607 myGShape = VraiPrism;
608 GeneratedShapeValid();
609 GluedFacesValid();
610
611 if(myFuse == 0) {
7fd59977 612 BRepAlgoAPI_Cut c(mySbase, myGShape);
7fd59977 613 if (c.IsDone()) {
614 myShape = c.Shape();
7fd59977 615 UpdateDescendants(c, myShape, Standard_False);
7fd59977 616 Done();
617 }
618 }
619 else {
620 thePrism.Curves(myCurves);
621 myBCurve = thePrism.BarycCurve();
622 GlobalPerform();
623 }
624}
625
626//=======================================================================
627//function : PerformFromEnd
628//purpose :
629//=======================================================================
630
631void BRepFeat_MakePrism::PerformFromEnd(const TopoDS_Shape& Until)
632{
0797d9d3 633#ifdef OCCT_DEBUG
7fd59977 634 Standard_Boolean trc = BRepFeat_GettraceFEAT();
635 if (trc) cout << "BRepFeat_MakePrism::PerformFromEnd(From,Until)" << endl;
636#endif
637 if (Until.IsNull()) {
9775fa61 638 throw Standard_ConstructionError();
7fd59977 639 }
640 if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
641 myDir.Reverse();
642 PerformUntilEnd();
643 return;
644 }
645 TopExp_Explorer exp;
646 exp.Init(Until, TopAbs_FACE);
647 if (!exp.More()) {
9775fa61 648 throw Standard_ConstructionError();
7fd59977 649 }
650 myPerfSelection = BRepFeat_SelectionShU;
651 PerfSelectionValid();
652 mySFrom.Nullify();
653 ShapeFromValid();
654 mySUntil = Until;
655 Standard_Boolean Trf = TransformShapeFU(1);
656 ShapeUntilValid();
657 Handle(Geom_Curve) C = TestCurve(myPbase,myDir);
658 Standard_Integer sens = SensOfPrism(C, mySUntil);
659 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
660 gp_Vec Vtra(-3*Height*sens/2.*myDir);
661 gp_Vec Vect(3*sens*Height*myDir);
662 LocOpe_Prism thePrism(myPbase,Vect,Vtra);
663 TopoDS_Shape VraiPrism = thePrism.Shape();
664
0d969553 665 if(!Trf) { // case face until
7fd59977 666 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
667 myGShape = VraiPrism;
668 GeneratedShapeValid();
669 myGluedF.Clear();
670 GluedFacesValid();
671 thePrism.Curves(myCurves);
672 myBCurve = thePrism.BarycCurve();
673 GlobalPerform();
674 }
0d969553 675 else { // case support
7fd59977 676 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
677 TColGeom_SequenceOfCurve scur;
678 scur.Clear();
679 scur.Append(C);
680 LocOpe_CSIntersector ASI1(mySUntil);
681 LocOpe_CSIntersector ASI2(mySbase);
682 ASI1.Perform(scur);
683 ASI2.Perform(scur);
7fd59977 684 TopAbs_Orientation OrU = TopAbs_FORWARD, OrF = TopAbs_FORWARD;
7fd59977 685 TopoDS_Face FUntil, FFrom;
686 if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
687 OrU = ASI1.Point(1,1).Orientation();
688 if(sens==-1) {
689 OrU = TopAbs::Reverse(OrU);
690 }
691 FUntil = ASI1.Point(1,1).Face();
692 }
693 if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
694 OrF = ASI2.Point(1,1).Orientation();
695// if(sens==1) OrF = TopAbs::Reverse(OrF);
696 FFrom = ASI2.Point(1 ,1).Face();
697 Handle(Geom_Surface) S = BRep_Tool::Surface(FFrom);
698 if (S->DynamicType() ==
699 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
700 S = Handle(Geom_RectangularTrimmedSurface)::
701 DownCast(S)->BasisSurface();
702 }
1c72dff6 703 BRepLib_MakeFace fac(S, Precision::Confusion());
7fd59977 704 mySFrom = fac.Face();
705 Trf = TransformShapeFU(0);
706 FFrom = TopoDS::Face(mySFrom);
707 }
093a3fe5 708
709 TopTools_ListOfShape aLTools;
7fd59977 710 TopoDS_Solid Sol = BRepFeat::Tool(mySUntil, FUntil, OrU);
711 if (!Sol.IsNull()) {
093a3fe5 712 aLTools.Append(Sol);
7fd59977 713 }
714 else {
715 NotDone();
716 myStatusError = BRepFeat_NullToolU;
717 return;
718 }
719
720 TopoDS_Solid Sol1 = BRepFeat::Tool(mySFrom, FFrom, OrF);
721 if (!Sol1.IsNull()) {
093a3fe5 722 aLTools.Append(Sol1);
7fd59977 723 }
724 else {
725 NotDone();
726 myStatusError = BRepFeat_NullToolF;
727 return;
728 }
093a3fe5 729 //
730 TopTools_ListOfShape aLObj;
731 aLObj.Append(VraiPrism);
732 //
733 BRepAlgoAPI_Cut trP;
734 trP.SetArguments(aLObj);
735 trP.SetTools(aLTools);
736 trP.Build();
737 //
7fd59977 738 UpdateDescendants(trP, trP.Shape(), Standard_False);
7fd59977 739 if(myFuse == 1 && !myJustFeat) {
7fd59977 740 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
741 myShape = f.Shape();
742 UpdateDescendants(f, myShape, Standard_False);
7fd59977 743 Done();
744 }
745 else if(myFuse == 0) {
7fd59977 746 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
747 myShape = c.Shape();
748 UpdateDescendants(c, myShape, Standard_False);
7fd59977 749 Done();
750 }
751 else {
752 myShape = trP.Shape();
093a3fe5 753 Done();
7fd59977 754 }
093a3fe5 755 }
7fd59977 756}
757
7fd59977 758//=======================================================================
759//function : PerformThruAll
760//purpose :
761//=======================================================================
762
763void BRepFeat_MakePrism::PerformThruAll()
764{
0797d9d3 765#ifdef OCCT_DEBUG
7fd59977 766 Standard_Boolean trc = BRepFeat_GettraceFEAT();
767 if (trc) cout << "BRepFeat_MakePrism::PerformThruAll()" << endl;
768#endif
769 mySUntil.Nullify();
770 ShapeUntilValid();
771 mySFrom.Nullify();
772 ShapeFromValid();
773 if(myFuse == 0) {
774 myPerfSelection = BRepFeat_NoSelection;
775 }
776 else {
777 myPerfSelection = BRepFeat_SelectionSh;
778 }
779 PerfSelectionValid();
780 myGluedF.Clear();
781 GluedFacesValid();
782
783 Standard_Real Height = HeightMax(mySbase, mySkface, mySFrom, mySUntil);
784 gp_Vec V(3*Height*myDir);
785 gp_Vec Vtra(-3*Height/2.*myDir);
786 LocOpe_Prism thePrism(myPbase,V,Vtra);
787 TopoDS_Shape VraiPrism = thePrism.Shape();
788 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
789
790 myGShape = VraiPrism;
791 GeneratedShapeValid();
792
793 if(myFuse == 0) {
7fd59977 794 BRepAlgoAPI_Cut c(mySbase, myGShape);
7fd59977 795 if (c.IsDone()) {
796 myShape = c.Shape();
7fd59977 797 UpdateDescendants(c, myShape, Standard_False);
7fd59977 798 Done();
799 }
800 }
801 else {
802 thePrism.Curves(myCurves);
803 myBCurve = thePrism.BarycCurve();
804 GlobalPerform();
805 }
806}
807
7fd59977 808//=======================================================================
809//function : PerformUntilHauteur
810//purpose :
811//=======================================================================
812
813void BRepFeat_MakePrism::PerformUntilHeight(const TopoDS_Shape& Until,
093a3fe5 814 const Standard_Real Length)
7fd59977 815{
0797d9d3 816#ifdef OCCT_DEBUG
7fd59977 817 Standard_Boolean trc = BRepFeat_GettraceFEAT();
818 if (trc) cout << "BRepFeat_MakePrism::PerformUntilHeight(Until,Length)" << endl;
819#endif
820 if (Until.IsNull()) {
821 Perform(Length);
822 }
823 if(Length == 0) {
824 Perform(Until);
825 }
826 TopExp_Explorer exp(Until, TopAbs_FACE);
827 if (!exp.More()) {
9775fa61 828 throw Standard_ConstructionError();
7fd59977 829 }
830 myGluedF.Clear();
831 myPerfSelection = BRepFeat_NoSelection;
832 PerfSelectionValid();
833 mySFrom.Nullify();
834 ShapeFromValid();
835 mySUntil = Until;
836 Standard_Boolean Trf = TransformShapeFU(1);
837 ShapeUntilValid();
838 Handle(Geom_Curve) C = TestCurve(myPbase,myDir);
839 Standard_Integer sens = SensOfPrism(C, mySUntil);
840 gp_Vec V(sens*Length*myDir);
841 LocOpe_Prism thePrism(myPbase,V);
842 TopoDS_Shape VraiPrism = thePrism.Shape();
843
844 if(!Trf) {
845 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
846
847 myGShape = VraiPrism;
848 GeneratedShapeValid();
7fd59977 849 GluedFacesValid();
7fd59977 850 thePrism.Curves(myCurves);
851 myBCurve = thePrism.BarycCurve();
852 GlobalPerform();
853 }
854 else {
855 MajMap(myPbase,thePrism,myMap,myFShape,myLShape);
856 TColGeom_SequenceOfCurve scur;
857 scur.Clear();
858 scur.Append(C);
859 LocOpe_CSIntersector ASI(mySUntil);
860 ASI.Perform(scur);
861 TopAbs_Orientation Or;
862 if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
863 if (myFuse == 1) {
864 Or = ASI.Point(1,1).Orientation();
865 }
866 else {
867 Or = ASI.Point(1,ASI.NbPoints(1)).Orientation();
868 }
869 if(sens==-1) Or=TopAbs::Reverse(Or);
870 TopoDS_Face FUntil = ASI.Point(1,1).Face();
871 TopoDS_Shape Comp;
872 BRep_Builder B;
873 B.MakeCompound(TopoDS::Compound(Comp));
874 TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
875 if (!S.IsNull()) B.Add(Comp,S);
876
7fd59977 877 BRepAlgoAPI_Cut trP(VraiPrism,Comp);
878 UpdateDescendants(trP, trP.Shape(), Standard_False);
7fd59977 879 if(myFuse == 1 && !myJustFeat) {
093a3fe5 880 BRepAlgoAPI_Fuse f(mySbase, trP.Shape());
881 myShape = f.Shape();
882 UpdateDescendants(f, myShape, Standard_False);
883 Done();
7fd59977 884 }
885 else if(myFuse == 0) {
093a3fe5 886 BRepAlgoAPI_Cut c(mySbase, trP.Shape());
887 myShape = c.Shape();
888 UpdateDescendants(c, myShape, Standard_False);
889 Done();
7fd59977 890 }
891 else {
093a3fe5 892 myShape = trP.Shape();
893 Done();
7fd59977 894 }
093a3fe5 895 }
7fd59977 896 }
897}
898
899//=======================================================================
900//function : Curves
0d969553 901//purpose : sequence of curves parallel to the axis of prism
7fd59977 902//=======================================================================
903
904void BRepFeat_MakePrism::Curves(TColGeom_SequenceOfCurve& scur)
905{
906 scur = myCurves;
907}
908
909//=======================================================================
910//function : BarycCurve
0d969553
Y
911//purpose : curve parallel to the axis of the prism passing through the center
912// of masses
7fd59977 913//=======================================================================
914
915Handle(Geom_Curve) BRepFeat_MakePrism::BarycCurve()
916{
917 return myBCurve;
918}
919
920
921//=======================================================================
922//function : HeightMax
0d969553
Y
923//purpose : Calculate the height of the prism following the parameters of
924// bounding box
7fd59977 925//=======================================================================
926
927static Standard_Real HeightMax(const TopoDS_Shape& theSbase,
928 const TopoDS_Face& theSkface,
929 const TopoDS_Shape& theSFrom,
930 const TopoDS_Shape& theSUntil)
931{
932 Bnd_Box Box;
933 BRepBndLib::Add(theSbase,Box);
934 BRepBndLib::Add(theSkface,Box);
935 if(!theSFrom.IsNull()) {
7fd59977 936 Standard_Boolean FacRevolInfini = Standard_False;
7fd59977 937 TopExp_Explorer exp;
938 exp.Init(theSFrom, TopAbs_EDGE);
939 for(; exp.More(); exp.Next()) {
940 TopExp_Explorer exp1;
941 exp1.Init(exp.Current(), TopAbs_VERTEX);
942 if(!exp1.More()) {
943 FacRevolInfini = Standard_True;
944 break;
945 }
946 }
947 if(!FacRevolInfini)
948 BRepBndLib::Add(theSFrom,Box);
949 }
a8195d65 950 if(!theSUntil.IsNull())
951 {
952 Standard_Boolean FacRevolInfini = Standard_False;
7fd59977 953 TopExp_Explorer exp;
954 exp.Init(theSUntil, TopAbs_EDGE);
a8195d65 955 for(; exp.More(); exp.Next())
956 {
7fd59977 957 TopExp_Explorer exp1;
958 exp1.Init(exp.Current(), TopAbs_VERTEX);
a8195d65 959 if(!exp1.More())
960 {
1d47d8d0 961 FacRevolInfini = Standard_True;
962 break;
7fd59977 963 }
964 }
965 if(!FacRevolInfini)
966 BRepBndLib::Add(theSUntil,Box);
967 }
968
969 Standard_Real c[6];
970
971 Box.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
972 Standard_Real parmin=c[0], parmax = c[0];
973 for(Standard_Integer i = 0 ; i < 6; i++) {
974 if(c[i] > parmax) parmax = c[i];
975 if(c[i] < parmin ) parmin = c[i];
976 }
0797d9d3 977//#ifndef OCCT_DEBUG
7fd59977 978 Standard_Real Height = fabs(2.*(parmax - parmin));
979//#else
980// Standard_Real Height = abs(2.*(parmax - parmin));
981//#endif
982 return(Height);
983}
984
985
986//=======================================================================
987//function : SensOfPrism
0d969553 988//purpose : Direction of the prism depending on the shape Until
7fd59977 989//=======================================================================
990Standard_Integer SensOfPrism(const Handle(Geom_Curve) C,
991 const TopoDS_Shape& Until)
992{
993 LocOpe_CSIntersector ASI1(Until);
994 TColGeom_SequenceOfCurve scur;
995 scur.Append(C);
996 ASI1.Perform(scur);
997 Standard_Integer sens = 1;
998 if(ASI1.IsDone() && ASI1.NbPoints(1) >= 1) {
999 if(ASI1.Point(1, 1).Parameter() < 0. &&
1000 ASI1.Point(1, ASI1.NbPoints(1)).Parameter() < 0.) {
1001 sens = -1;
1002 }
1003 }
1004 else if(BRepFeat::ParametricBarycenter(Until,C) < 0) {
1005 sens = -1;
1006 }
1007 else {}
1008 return sens;
1009}
1010
7fd59977 1011//=======================================================================
1012//function : MajMap
0d969553 1013//purpose : management of descendants
7fd59977 1014//=======================================================================
1015
1016static void MajMap(const TopoDS_Shape& theB,
1017 const LocOpe_Prism& theP,
1018 TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1019 TopoDS_Shape& theFShape, // myFShape
1020 TopoDS_Shape& theLShape) // myLShape
1021{
1022 TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1023 if (exp.More()) {
1024 theFShape = exp.Current();
1025 TopTools_ListOfShape thelist2;
1026 theMap.Bind(theFShape, thelist2);
1027 for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1028 theMap(theFShape).Append(exp.Current());
1029 }
1030 }
1031
1032 exp.Init(theP.LastShape(),TopAbs_WIRE);
1033 if (exp.More()) {
1034 theLShape = exp.Current();
1035 TopTools_ListOfShape thelist3;
1036 theMap.Bind(theLShape, thelist3);
1037 for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1038 theMap(theLShape).Append(exp.Current());
1039 }
1040 }
1041
1042 for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1043 if (!theMap.IsBound(exp.Current())) {
1044 TopTools_ListOfShape thelist4;
1045 theMap.Bind(exp.Current(), thelist4);
1046 theMap(exp.Current()) = theP.Shapes(exp.Current());
1047 }
1048 }
1049}
1050
1051
1052//=======================================================================
1053//function : MajMap
0d969553 1054//purpose : management of descendants
7fd59977 1055//=======================================================================
1056
1057static Handle(Geom_Curve) TestCurve(const TopoDS_Shape& Base,
1058 const gp_Vec& V)
1059{
1060 gp_Pnt bar(0., 0., 0.);
1061 TColgp_SequenceOfPnt spt;
1062 LocOpe::SampleEdges(Base,spt);
1063 for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
1064 const gp_Pnt& pvt = spt(jj);
1065 bar.ChangeCoord() += pvt.XYZ();
1066 }
1067 bar.ChangeCoord().Divide(spt.Length());
1068 gp_Ax1 newAx(bar,V);
1069 Handle(Geom_Line) theLin = new Geom_Line(newAx);
1070 return theLin;
1071}
1072
1073
1074
1075
1076//=======================================================================
1077//function : ToFuse
0d969553 1078//purpose : face SameDomaine or not
7fd59977 1079//=======================================================================
1080
5b111128 1081static Standard_Boolean ToFuse (const TopoDS_Face& F1, const TopoDS_Face& F2)
7fd59977 1082{
1083 if (F1.IsNull() || F2.IsNull()) {
1084 return Standard_False;
1085 }
1086
1087 Handle(Geom_Surface) S1,S2;
1088 TopLoc_Location loc1, loc2;
1089 Handle(Standard_Type) typS1,typS2;
1090 const Standard_Real tollin = Precision::Confusion();
1091 const Standard_Real tolang = Precision::Angular();
1092
1093 S1 = BRep_Tool::Surface(F1,loc1);
1094 S2 = BRep_Tool::Surface(F2,loc2);
1095
1096 typS1 = S1->DynamicType();
1097 typS2 = S2->DynamicType();
1098
1099 if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
c5f3a425 1100 S1 = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
7fd59977 1101 typS1 = S1->DynamicType();
1102 }
1103
1104 if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
c5f3a425 1105 S2 = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
7fd59977 1106 typS2 = S2->DynamicType();
1107 }
1108
1109 if (typS1 != typS2) {
1110 return Standard_False;
1111 }
1112
1113
1114 Standard_Boolean ValRet = Standard_False;
1115 if (typS1 == STANDARD_TYPE(Geom_Plane)) {
c5f3a425 1116 gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
1117 gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
7fd59977 1118
5b111128 1119 // apply locations
1120 if (! loc1.IsIdentity())
1121 pl1.Transform (loc1.Transformation());
1122 if (! loc2.IsIdentity())
1123 pl2.Transform (loc2.Transformation());
1124
7fd59977 1125 if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
1126 ValRet = Standard_True;
1127 }
1128 }
1129
1130 return ValRet;
1131}
1132
1133
1134
1135
1136
1137