0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / LocOpe / LocOpe_Pipe.cxx
CommitLineData
b311480e 1// Created on: 1996-09-04
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
18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
42cf5bc1 20#include <BSplCLib.hxx>
7fd59977 21#include <Geom_BSplineCurve.hxx>
42cf5bc1 22#include <Geom_Curve.hxx>
23#include <Geom_Plane.hxx>
24#include <Geom_RectangularTrimmedSurface.hxx>
25#include <Geom_Surface.hxx>
26#include <GeomConvert.hxx>
7fd59977 27#include <gp_Pln.hxx>
42cf5bc1 28#include <LocOpe.hxx>
29#include <LocOpe_BuildShape.hxx>
30#include <LocOpe_Pipe.hxx>
7fd59977 31#include <Precision.hxx>
42cf5bc1 32#include <Standard_DomainError.hxx>
33#include <Standard_NoSuchObject.hxx>
34#include <TColgp_Array1OfPnt.hxx>
35#include <TColStd_Array1OfInteger.hxx>
36#include <TColStd_Array1OfReal.hxx>
37#include <TopExp.hxx>
38#include <TopExp_Explorer.hxx>
39#include <TopoDS.hxx>
40#include <TopoDS_Edge.hxx>
41#include <TopoDS_Face.hxx>
42#include <TopoDS_Shape.hxx>
43#include <TopoDS_Wire.hxx>
44#include <TopTools_DataMapOfShapeListOfShape.hxx>
45#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46#include <TopTools_ListIteratorOfListOfShape.hxx>
47#include <TopTools_MapIteratorOfMapOfShape.hxx>
48#include <TopTools_MapOfShape.hxx>
7fd59977 49
50static TopAbs_Orientation Orientation(const TopoDS_Shape&,
51 const TopoDS_Shape&);
52
53
54//=======================================================================
55//function : LocOpe_Pipe
56//purpose :
57//=======================================================================
58
59LocOpe_Pipe::LocOpe_Pipe(const TopoDS_Wire& Spine,
60 const TopoDS_Shape& Profile) :
471ce736 61 myPipe(Spine,Profile)
7fd59977 62{
63
64 TopoDS_Shape Result = myPipe.Shape();
65
66 // On enleve les faces generees par les edges de connexite du profile,
67 // et on fusionne les plans si possible
68
69 TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
70 TopExp::MapShapesAndAncestors(Profile,TopAbs_EDGE,TopAbs_FACE,theEFMap);
71 TopExp_Explorer exp;
72 TopTools_ListOfShape Empty;
73 TopTools_ListIteratorOfListOfShape it;
74
75 TopTools_ListOfShape goodfaces;
76
77 for (Standard_Integer i=1; i<=theEFMap.Extent(); i++) {
78 const TopoDS_Edge& edgpr = TopoDS::Edge(theEFMap.FindKey(i));
79 myMap.Bind(edgpr,Empty);
80 if (theEFMap(i).Extent() >= 2) {
81 // on ne prend pas les faces generees
82 }
83 else {
84 TopTools_MapOfShape MapFac; // on mappe les plans generes par cet edge
85 for (exp.Init(Spine,TopAbs_EDGE); exp.More(); exp.Next()) {
86 const TopoDS_Edge& edgsp = TopoDS::Edge(exp.Current());
87 TopoDS_Face resfac = myPipe.Face(edgsp,edgpr);
88 if (!resfac.IsNull()) {
89 Handle(Geom_Surface) P = BRep_Tool::Surface(resfac);
90 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
91 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
92 }
93 if (P->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
94 MapFac.Add(resfac);
95 }
96 else {
97 myMap(edgpr).Append(resfac);
98 goodfaces.Append(resfac);
99 }
100 }
101 }
102
103 // Chercher les composantes connexes sur cet ensemble de faces., avec meme
104 // support geometrique
105
106 TopTools_MapIteratorOfMapOfShape itm(MapFac);
107 if (MapFac.Extent() <= 1) { // un seul plan. Rien a faire
108 if (MapFac.Extent() == 1) {
109 myMap(edgpr).Append(itm.Key());
110 goodfaces.Append(itm.Key());
111 }
112 continue;
113 }
114
115 while (MapFac.Extent() >= 2) {
116 itm.Reset();
117 TopTools_ListOfShape FacFuse;
118 TopoDS_Face FaceRef = TopoDS::Face(itm.Key());
119 FacFuse.Append(FaceRef);
120 Handle(Geom_Surface) P = BRep_Tool::Surface(FaceRef);
121 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
122 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
123 }
124 gp_Pln Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
125
126 for (itm.Next(); itm.More(); itm.Next()) {
127 P = BRep_Tool::Surface(TopoDS::Face(itm.Key()));
128 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
129 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
130 }
131 gp_Pln Pl = Handle(Geom_Plane)::DownCast(P)->Pln();
132 if (Pl.Axis().IsParallel(Plref.Axis(),Precision::Angular()) &&
133 Plref.Contains(Pl.Location(),Precision::Confusion())) {
134 FacFuse.Append(itm.Key());
135 }
136 }
137
138 // FacFuse contient des faces de meme support. Il faut en faire
139 // des composantes connexes
140
141 while (FacFuse.Extent() >= 2) {
142 FaceRef = TopoDS::Face(FacFuse.First());
143 // Recuperer l'orientation
144 TopAbs_Orientation orref = Orientation(FaceRef,Result);
145 P = BRep_Tool::Surface(FaceRef);
146 if (P->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
147 P = Handle(Geom_RectangularTrimmedSurface)::DownCast(P)->BasisSurface();
148 }
149 Plref = Handle(Geom_Plane)::DownCast(P)->Pln();
150 gp_Dir Dirref(Plref.Axis().Direction());
0ebaa4db 151 if ((Plref.Direct() && orref == TopAbs_REVERSED) ||
152 (!Plref.Direct() && orref == TopAbs_FORWARD)) {
7fd59977 153 Dirref.Reverse();
154 }
155
156 TopTools_MapOfShape MapEd;
157 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
158 exp.More(); exp.Next()) {
159 MapEd.Add(exp.Current());
160 }
161
162 MapFac.Remove(FaceRef);
163 FacFuse.RemoveFirst(); // on enleve FaceRef
164 Standard_Boolean FaceToFuse = Standard_False;
165 Standard_Boolean MoreFound;
166
167
168 do {
169 MoreFound = Standard_False;
170 for (it.Initialize(FacFuse); it.More(); it.Next()) {
171 for (exp.Init(it.Value(),TopAbs_EDGE);
172 exp.More(); exp.Next()) {
173 if (MapEd.Contains(exp.Current())) {
174 FaceToFuse = Standard_True;
175 MoreFound = Standard_True;
176 break;
177 }
178 }
179 if (exp.More()) {
180 break;
181 }
182 }
183 if (MoreFound) {
184 const TopoDS_Face& fac = TopoDS::Face(it.Value());
185 TopAbs_Orientation orrelat = Orientation(fac,Result);
186 Handle(Geom_Surface) OtherP = BRep_Tool::Surface(fac);
187 if (OtherP->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
188 OtherP = Handle(Geom_RectangularTrimmedSurface)::
189 DownCast(OtherP)->BasisSurface();
190 }
191 gp_Pln Pl = Handle(Geom_Plane)::DownCast(OtherP)->Pln();
192 gp_Dir Dirpl(Pl.Axis().Direction());
0ebaa4db 193 if ((Pl.Direct() && orrelat == TopAbs_REVERSED) ||
194 (!Plref.Direct() && orrelat == TopAbs_FORWARD)) {
7fd59977 195 Dirpl.Reverse();
196 }
197 if (Dirpl.Dot(Dirref) > 0) {
198 orrelat = TopAbs_FORWARD;
199 }
200 else {
201 orrelat = TopAbs_REVERSED;
202 }
203 for (exp.Init(fac.Oriented(orrelat),TopAbs_EDGE);
204 exp.More(); exp.Next()) {
205 if (!MapEd.Add(exp.Current())) {
206 MapEd.Remove(exp.Current());
207 }
208 }
209 MapFac.Remove(fac);
210 FacFuse.Remove(it);
211 }
212 } while (MoreFound);
213
214 if (FaceToFuse) {
215 TopoDS_Face NewFace;
216 BRep_Builder B;
217 B.MakeFace(NewFace,P,BRep_Tool::Tolerance(FaceRef));
218 TopoDS_Wire NewWire;
219 B.MakeWire(NewWire);
220 for (TopTools_MapIteratorOfMapOfShape itm2(MapEd);
221 itm2.More(); itm2.Next()) {
222 B.Add(NewWire,itm2.Key());
223 }
224 exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
225 NewWire.Orientation(exp.Current().Orientation());
226 B.Add(NewFace,NewWire);
227 myMap(edgpr).Append(NewFace);
228 goodfaces.Append(NewFace);
229 }
230 }
231 if (FacFuse.Extent() == 1) {
232 MapFac.Remove(FacFuse.First());
233 myMap(edgpr).Append(FacFuse.First());
234 goodfaces.Append(FacFuse.First());
235 }
236 }
237 }
238 }
239
240 for (exp.Init(myPipe.FirstShape(),TopAbs_FACE); exp.More(); exp.Next()) {
241 goodfaces.Append(exp.Current());
242 }
243 for (exp.Init(myPipe.LastShape(),TopAbs_FACE); exp.More(); exp.Next()) {
244 goodfaces.Append(exp.Current());
245 }
246
247 LocOpe_BuildShape BS(goodfaces);
248 myRes = BS.Shape();
249}
250
251
252//=======================================================================
253//function : Shape
254//purpose :
255//=======================================================================
256
257const TopoDS_Shape& LocOpe_Pipe::Shape () const
258{
259 return myRes;
260}
261
262
263//=======================================================================
264//function : Shapes
265//purpose :
266//=======================================================================
267
268const TopTools_ListOfShape& LocOpe_Pipe::Shapes (const TopoDS_Shape& S)
269{
270 TopAbs_ShapeEnum typS = S.ShapeType();
271 if (typS != TopAbs_EDGE && typS != TopAbs_VERTEX) {
9775fa61 272 throw Standard_DomainError();
7fd59977 273 }
274// for (TopExp_Explorer exp(myPipe.Profile(),typS); exp.More(); exp.Next()) {
275 TopExp_Explorer exp(myPipe.Profile(),typS) ;
276 for ( ; exp.More(); exp.Next()) {
277 if (exp.Current().IsSame(S)) {
278 break;
279 }
280 }
281 if (!exp.More()) {
9775fa61 282 throw Standard_NoSuchObject();
7fd59977 283 }
284
285 myGShap.Clear();
286 if (typS == TopAbs_VERTEX) {
287 const TopoDS_Vertex& VProfile = TopoDS::Vertex(S);
288 for (exp.Init(myPipe.Spine(),TopAbs_EDGE); exp.More(); exp.Next()) {
289 const TopoDS_Edge& edsp = TopoDS::Edge(exp.Current());
290 TopoDS_Edge resed = myPipe.Edge(edsp,VProfile);
291 if (!resed.IsNull()) {
292 myGShap.Append(resed);
293 }
294 }
295 return myGShap;
296 }
297 // TopAbs_EDGE
298 const TopoDS_Edge& EProfile = TopoDS::Edge(S);
299 return myMap(EProfile);
300}
301
302
303//=======================================================================
304//function : GetCurves
305//purpose :
306//=======================================================================
307
308const TColGeom_SequenceOfCurve&
309 LocOpe_Pipe::Curves(const TColgp_SequenceOfPnt& Spt)
310{
311
312 myCrvs.Clear();
313 TopTools_MapOfShape Map;
314
315 Standard_Integer i , j , k , Nbpnt = Spt.Length();
316 Standard_Real p1,p2;
317// gp_Pnt ptbid;
318
319 for ( i = 1; i <= Nbpnt; i++) {
320 gp_Pnt P1 = Spt(i);
321 Standard_Integer MaxDeg = 0;
322 TColGeom_SequenceOfCurve seq;
323 TopoDS_Wire W = myPipe.PipeLine(P1);
324
325 TopExp_Explorer ex(W, TopAbs_EDGE);
326 for (; ex.More(); ex.Next()) {
327 Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
328 Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
329 if (C.IsNull()) {
330 continue;
331 }
332 MaxDeg = Max(MaxDeg,C->Degree());
333 P1 = C->Value(p2);
334 if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
335 C->Segment(p1,p2);
336 }
337 Standard_Integer Nbkn = C->NbKnots();
338 TColStd_Array1OfReal Tkn(1,Nbkn);
339 C->Knots(Tkn);
340 BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
341 C->SetKnots(Tkn);
342 seq.Append(C);
343 }
344
345 Handle(Geom_Curve) newC;
346 Standard_Integer Nbkn=0 ,Nbp=0;
347 Standard_Integer Nbcurv = seq.Length();
348 if (Nbcurv == 0) {
349 myCrvs.Append(newC);
350 continue;
351 }
352
353 Handle(Geom_BSplineCurve) Bsp;
354 for (j=1; j<=Nbcurv; j++) {
355 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
356 Bsp->IncreaseDegree(MaxDeg);
357 Nbp += Bsp->NbPoles();
358 Nbkn += Bsp->NbKnots();
359 }
360 Nbp -= Nbcurv-1;
361 Nbkn -= Nbcurv-1;
362 TColStd_Array1OfReal Tkn(1,Nbkn);
363 TColStd_Array1OfInteger Tmu(1,Nbkn);
364 TColgp_Array1OfPnt Tpol(1,Nbp);
365 Standard_Integer Ik=0,Ip=0;
366
367 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
368 for ( k = 1; k<= Bsp->NbPoles(); k++) {
369 Ip++;
370 Tpol(Ip) = Bsp->Pole(k);
371 }
372 for (k = 1; k<= Bsp->NbKnots(); k++) {
373 Ik++;
374 Tkn(Ik) = Bsp->Knot(k);
375 Tmu(Ik) = Bsp->Multiplicity(k);
376 }
377 Tmu(Ik)--;
378
379 for (j=2; j<=Nbcurv; j++) {
380 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
381 for (k = 2; k<= Bsp->NbPoles(); k++) {
382 Ip++;
383 Tpol(Ip) = Bsp->Pole(k);
384 }
385 for (k = 2; k<= Bsp->NbKnots(); k++) {
386 Ik++;
387 Tkn(Ik) = Bsp->Knot(k);
388 Tmu(Ik) = Bsp->Multiplicity(k);
389 }
390 Tmu(Ik)--;
391 }
392 Tmu(Ik)++;
393 newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);
394 myCrvs.Append(newC);
395 }
396
397 return myCrvs;
398}
399
400
401//=======================================================================
402//function : Orientation
403//purpose : static, not member
404//=======================================================================
405
406static TopAbs_Orientation Orientation(const TopoDS_Shape& Sub,
407 const TopoDS_Shape& S)
408{
409 TopExp_Explorer exp;
410 for (exp.Init(S,Sub.ShapeType()); exp.More(); exp.Next()) {
411 if (exp.Current().IsSame(Sub)) {
412 return exp.Current().Orientation();
413 }
414 }
9775fa61 415 throw Standard_NoSuchObject();
7fd59977 416}
417
418
419//=======================================================================
420//function : BarycCurve
421//purpose :
422//=======================================================================
423
424Handle(Geom_Curve) LocOpe_Pipe::BarycCurve()
425{
426 Standard_Integer j , k ;
427
428 gp_Pnt bar(0., 0., 0.);
429 TColgp_SequenceOfPnt spt;
430 TopoDS_Shape Base = FirstShape();
431 LocOpe::SampleEdges(Base, spt);
432 for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
433 const gp_Pnt& pvt = spt(jj);
434 bar.ChangeCoord() += pvt.XYZ();
435 }
436 bar.ChangeCoord().Divide(spt.Length());
437
438 Standard_Real p1,p2;
439// gp_Pnt ptbid;
440 gp_Pnt P1 = bar;
441
442 Standard_Integer MaxDeg = 0;
443 TColGeom_SequenceOfCurve seq;
444 TopoDS_Wire W = myPipe.PipeLine(P1);
445
446 TopExp_Explorer ex(W, TopAbs_EDGE);
447 for (; ex.More(); ex.Next()) {
448 Handle(Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(ex.Current()), p1, p2);
449 Handle(Geom_BSplineCurve) C = GeomConvert::CurveToBSplineCurve (C1);
450
451 if (C.IsNull()) {
452 continue;
453 }
454 MaxDeg = Max(MaxDeg,C->Degree());
455 P1 = C->Value(p2);
456 if (p1 != C->FirstParameter() || p2 != C->LastParameter()) {
457 C->Segment(p1,p2);
458 }
459 Standard_Integer Nbkn = C->NbKnots();
460 TColStd_Array1OfReal Tkn(1,Nbkn);
461 C->Knots(Tkn);
462 BSplCLib::Reparametrize(seq.Length(),seq.Length()+1,Tkn);
463 C->SetKnots(Tkn);
464 seq.Append(C);
465 }
466 Handle(Geom_Curve) newC;
467 Standard_Integer Nbkn=0 ,Nbp=0;
468 Standard_Integer Nbcurv = seq.Length();
469 if (Nbcurv == 0) {
470 myCrvs.Append(newC);
471 }
472 Handle(Geom_BSplineCurve) Bsp;
473 for ( j=1; j<=Nbcurv; j++) {
474 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
475 Bsp->IncreaseDegree(MaxDeg);
476 Nbp += Bsp->NbPoles();
477 Nbkn += Bsp->NbKnots();
478 }
479 Nbp -= Nbcurv-1;
480 Nbkn -= Nbcurv-1;
481 TColStd_Array1OfReal Tkn(1,Nbkn);
482 TColStd_Array1OfInteger Tmu(1,Nbkn);
483 TColgp_Array1OfPnt Tpol(1,Nbp);
484 Standard_Integer Ik=0,Ip=0;
485
486 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(1));
487 for ( k = 1; k<= Bsp->NbPoles(); k++) {
488 Ip++;
489 Tpol(Ip) = Bsp->Pole(k);
490 }
491 for (k = 1; k<= Bsp->NbKnots(); k++) {
492 Ik++;
493 Tkn(Ik) = Bsp->Knot(k);
494 Tmu(Ik) = Bsp->Multiplicity(k);
495 }
496 Tmu(Ik)--;
497
498 for (j=2; j<=Nbcurv; j++) {
499 Bsp = Handle(Geom_BSplineCurve)::DownCast(seq(j));
500 for (k = 2; k<= Bsp->NbPoles(); k++) {
501 Ip++;
502 Tpol(Ip) = Bsp->Pole(k);
503 }
504 for (k = 2; k<= Bsp->NbKnots(); k++) {
505 Ik++;
506 Tkn(Ik) = Bsp->Knot(k);
507 Tmu(Ik) = Bsp->Multiplicity(k);
508 }
509 Tmu(Ik)--;
510 }
511 Tmu(Ik)++;
512 newC = new Geom_BSplineCurve(Tpol,Tkn,Tmu,MaxDeg);
513
514 return newC;
515}
516
517