0022312: Translation of french commentaries in OCCT files
[occt.git] / src / Draft / Draft_Modification_1.cxx
CommitLineData
7fd59977 1// File: Draft_Modification_1.cxx
2// Created: Fri Dec 2 17:11:53 1994
3// Author: Jacques GOUSSARD
4
5#include <Draft_Modification.jxx>
6
7#include <BRep_Tool.hxx>
8#include <BRep_Builder.hxx>
9
10#include <BRepLib_MakeFace.hxx>
11
12#include <TopLoc_Location.hxx>
13#include <TopExp_Explorer.hxx>
14#include <TopTools_ListIteratorOfListOfShape.hxx>
15
16#include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
17#include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
18#include <Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx>
19#include <Draft_FaceInfo.hxx>
20#include <Draft_EdgeInfo.hxx>
21#include <Draft_VertexInfo.hxx>
22#include <BRep_Tool.hxx>
23#include <BRep_Tool.hxx>
24
25#include <Geom_Surface.hxx>
26#include <Geom_RectangularTrimmedSurface.hxx>
27
28
29#include <Geom2d_Line.hxx>
30#include <Geom_Plane.hxx>
31#include <Geom_SurfaceOfLinearExtrusion.hxx>
32#include <Geom_CylindricalSurface.hxx>
33#include <Geom_ConicalSurface.hxx>
34#include <Geom_Curve.hxx>
35#include <Geom_Line.hxx>
36#include <Geom_Circle.hxx>
37#include <Geom_Ellipse.hxx>
38#include <Geom_Parabola.hxx>
39#include <Geom_Hyperbola.hxx>
40#include <Geom_TrimmedCurve.hxx>
41#include <GeomAdaptor_Curve.hxx>
42#include <GeomAdaptor_Surface.hxx>
43#include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
44
45#include <gp_Vec.hxx>
46#include <gp_Lin.hxx>
47#include <gp_Pln.hxx>
48#include <gp_Circ.hxx>
49#include <gp_Elips.hxx>
50#include <gp_Parab.hxx>
51#include <gp_Hypr.hxx>
52
53#include <IntCurveSurface_HInter.hxx>
54#include <GeomInt_IntSS.hxx>
55#include <IntCurveSurface_IntersectionPoint.hxx>
56#include <IntAna_QuadQuadGeo.hxx>
57#include <IntAna_IntConicQuad.hxx>
58
59#include <Extrema_ExtPC.hxx>
60#include <BRepExtrema_ExtPC.hxx>
61#include <BRepExtrema_ExtCF.hxx>
62
63#include <Standard_DomainError.hxx>
64#include <Standard_Failure.hxx>
65#include <Standard_NotImplemented.hxx>
66
67#include <TopTools_MapOfShape.hxx>
68#include <TopTools_MapIteratorOfMapOfShape.hxx>
69
70#include <gp.hxx>
71#include <Precision.hxx>
72#include <ElCLib.hxx>
73#include <ElSLib.hxx>
74#include <BRepTools.hxx>
75#include <TopoDS.hxx>
76#include <TopExp.hxx>
77
78#include <GeomAdaptor_HCurve.hxx>
79#include <GeomAdaptor_HSurface.hxx>
80#include <GeomAPI_ProjectPointOnSurf.hxx>
81
82#include <GeomAPI_ProjectPointOnCurve.hxx>
83
84#include <Geom2d_TrimmedCurve.hxx>
85#include <Geom2dAPI_ProjectPointOnCurve.hxx>
86#include <Geom2d_BSplineCurve.hxx>
87#include <Geom2dConvert.hxx>
88#include <Geom2dAdaptor_HCurve.hxx>
89#include <Adaptor3d_CurveOnSurface.hxx>
90
91#include <GeomProjLib.hxx>
92#include <TColgp_Array1OfPnt2d.hxx>
93#include <Geom2d_BezierCurve.hxx>
94#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
95
96#include <Adaptor3d_HCurveOnSurface.hxx>
97#include <ProjLib_CompProjectedCurve.hxx>
98#include <ProjLib_HCompProjectedCurve.hxx>
99#include <Approx_CurveOnSurface.hxx>
100
101#include <GeomConvert_CompCurveToBSplineCurve.hxx>
102
103
104static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
105 Draft_DataMapOfEdgeEdgeInfo&,
106 const TopoDS_Vertex&,
107 Draft_VertexInfo&,
108 GeomAdaptor_Curve&,
109 GeomAdaptor_Surface&);
110
111static Standard_Real Parameter(const Handle(Geom_Curve)&,
112 const gp_Pnt&,
113 Standard_Integer&);
114
115static Standard_Real SmartParameter(Draft_EdgeInfo&,
116 const Standard_Real EdgeTol,
117 const gp_Pnt&,
118 const Standard_Integer,
119 const Handle(Geom_Surface)&,
120 const Handle(Geom_Surface)&);
121
122static TopAbs_Orientation Orientation(const TopoDS_Shape&,
123 const TopoDS_Face&);
124
125static Standard_Boolean FindRotation(const gp_Pln&,
126 const TopAbs_Orientation,
127 const gp_Dir&,
128 const Standard_Real,
129 const gp_Pln&,
130 gp_Ax1&,
131 Standard_Real&);
132
133
134//=======================================================================
135//function : InternalAdd
136//purpose :
137//=======================================================================
138
139Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
140 const gp_Dir& Direction,
141 const Standard_Real Angle,
142 const gp_Pln& NeutralPlane,
143 const Standard_Boolean Flag)
144{
145
146 if (myFMap.IsBound(F)) {
147 return (badShape.IsNull());
148 }
149
150 TopAbs_Orientation oris = Orientation(myShape,F);
151 TopLoc_Location Lo;
152 //gp_Dir NewDirection = Direction;
153 //Standard_Real NewAngle = Angle;
154 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Lo);
155 S = Handle(Geom_Surface)::DownCast(S->Transformed(Lo.Transformation()));
156 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
157 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
158 }
159 Handle(Geom_Surface) NewS;
160 Handle(Geom_Circle) theCircle;
161
162 Standard_Boolean postponed = (Flag == Standard_False);
163 if (postponed) {
164 Handle(Standard_Type) typS = S->DynamicType();
165 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
166 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
167 gp_Circ Cir;
168 if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
169 gp_Cylinder cyl =
170 Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
171 gp_Ax1 axcyl = cyl.Axis();
172 Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
173 gp_Vec VV(cyl.Location(),NeutralPlane.Location());
174 Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
175 }
176 else {
177 Handle(Geom_Curve) Cbas =
178 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
179 gp_Dir theDirextr =
180 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
181
182 if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
183 Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
184 }
185 if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
186 Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
187 gp_Dir dircir = Cir.Axis().Direction();
188 if (!Direction.IsParallel(dircir,Precision::Angular())) {
189 badShape = F;
190 errStat = Draft_FaceRecomputation;
191 return Standard_False;
192 }
193 }
194 else {
195 badShape = F;
196 errStat = Draft_FaceRecomputation;
197 return Standard_False;
198 }
199
200 gp_Ax3 Axis = NeutralPlane.Position();
201 Standard_Real L =
202 gp_Vec(Cir.Location(),Axis.Location()).
203 Dot(Axis.Direction());
204 Standard_Real Cos = theDirextr.Dot(Axis.Direction());
205 gp_Vec VV = ( L / Cos) * theDirextr;
206 Cir.Translate(VV);
207 }
208
209 theCircle = new Geom_Circle(Cir);
210
211 }
212 else {
213 postponed = Standard_False;
214 }
215 }
216
217
218 if (!postponed) {
219 NewS = NewSurface(S,oris,Direction,Angle,NeutralPlane);
220 if (NewS.IsNull()) {
221 badShape = F;
222 errStat = Draft_FaceRecomputation;
223 return Standard_False;
224 }
225 // Pour eviter certains pbs sur restrictions infinies
226 const Handle(Standard_Type)& typs = NewS->DynamicType();
227 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
228 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
229 Standard_Real umin,umax,vmin,vmax;
230 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
231 if (!Precision::IsNegativeInfinite(vmin) &&
232 !Precision::IsPositiveInfinite(vmax)) {
233 Standard_Real deltav = 10.*(vmax-vmin);
234 if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
235 vmin = vmin - deltav;
236 vmax = vmax + deltav;
237 }
238 else {
239 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
240 Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
241 if (vmin < Vapex) { // vmax ne doit pas exceder Vapex
242 if (vmax + deltav > Vapex) {
243 vmax = Vapex;
244 vmin = vmin - 10.*(vmax - vmin);
245 // JAG debug pour eviter apex
246 vmax = vmax-Precision::Confusion();
247 }
248 else {
249 vmin = vmin - deltav;
250 vmax = vmax + deltav;
251 }
252 }
253 else { // on a Vapex <= vmin < vmax
254 if (vmin - deltav < Vapex) {
255 vmin = Vapex;
256 vmax = vmax + 10.*(vmax - vmin);
257 // JAG debug pour eviter apex
258 vmin = vmin+Precision::Confusion();
259 }
260 else {
261 vmin = vmin - deltav;
262 vmax = vmax + deltav;
263 }
264 }
265 }
266 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*PI,vmin,vmax);
267 }
268 }
269 }
270
271 if (postponed || S != NewS) {
272 Draft_FaceInfo FI(NewS,Standard_True);
273 FI.RootFace(curFace);
274 myFMap.Bind(F,FI);
275 if (postponed) {
276 myFMap(F).ChangeCurve() = theCircle;
277 }
278 }
279
280 TopExp_Explorer expl(F,TopAbs_EDGE);
281 TopTools_MapOfShape MapOfE;
282 while (expl.More() && badShape.IsNull()) {
283 const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
284 if (!myEMap.IsBound(edg)) {
285 Standard_Boolean addedg = Standard_False;
286 Standard_Boolean addface = Standard_False;
287 TopoDS_Face OtherF;
288 // if (BRep_Tool::IsClosed(edg,F)) {
289 if (BRepTools::IsReallyClosed(edg,F)) {
290 addedg = Standard_True;
291 addface = Standard_False;
292 }
293 else {
294 // Chercher l autre face contenant l edge.
295 TopTools_ListIteratorOfListOfShape it;
296 it.Initialize(myEFMap.FindFromKey(edg));
297 Standard_Integer nbother = 0;
298 while (it.More()) {
299 if (!it.Value().IsSame(F)) {
300 if (OtherF.IsNull()) {
301 OtherF = TopoDS::Face(it.Value());
302 }
303 nbother++;
304 }
305 it.Next();
306 }
307 if (nbother >=2) {
308 badShape = edg;
309 errStat = Draft_EdgeRecomputation;
310 }
311 else if (! OtherF.IsNull() &&
312 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
313 addface= Standard_True;
314 addedg = Standard_True;
315 }
316 else if (nbother == 0) { // jag : ajout du 8 Novembre 95 : bord libre
317 // badShape = F;
318 }
319 }
320 if (addedg) {
321 if (postponed) {
322 myFMap(F).Add(OtherF);
323 }
324 Standard_Real f,l;
325 TopLoc_Location L;
326 Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
327 C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
328 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
329 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
330 }
331 Handle(Geom_Curve) NewC;
332 Draft_EdgeInfo EInf(Standard_True);
333 if(postponed) {
334 EInf.Add(F);
335 EInf.Add(OtherF);
336
337 // recherche du point fixe
338 Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
339 if (aLocalGeom.IsNull()) {
340 badShape = edg;
341 errStat = Draft_EdgeRecomputation;
342 }
343 else {
344 gp_Lin lin = aLocalGeom->Lin();
345 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
346 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
347 EInf.Tangent(ilipl.Point(1));
348 }
349 else {
350 badShape = edg;
351 errStat = Draft_EdgeRecomputation;
352 }
353 }
354 }
355 else {
356 NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
357 if (NewC.IsNull()) {
358 badShape = edg;
359 errStat = Draft_EdgeRecomputation;
360 }
361 }
362
363 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
364 if (!T.IsNull()) NewC = T->BasisCurve();
365 EInf.ChangeGeometry() = NewC;
366
367 EInf.RootFace(curFace);
368 myEMap.Bind(edg,EInf);
369 MapOfE.Add(edg);
370 if (addface) {
371 Standard_Boolean Fl = Flag;
372 Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
373 if (alocalSurface->DynamicType() ==
374 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
375 alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
376 DownCast(alocalSurface)->BasisSurface();
377 }
378 Handle(Standard_Type) typS = alocalSurface->DynamicType();
379 if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
380 typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
381 if ( myFMap.IsBound(F)) {
382 if ( Flag == Standard_False && !postponed) {
383 myFMap.UnBind(F);
384 TopTools_MapIteratorOfMapOfShape itm(MapOfE);
385 for ( ; itm.More(); itm.Next())
386 myEMap.UnBind(TopoDS::Edge(itm.Key()));
387 }
388 }
389 }
390 InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
391 }
392 }
393 }
394 expl.Next();
395 }
396 return (badShape.IsNull());
397}
398
399
400//=======================================================================
401//function : Propagate
402//purpose :
403//=======================================================================
404
405Standard_Boolean Draft_Modification::Propagate ()
406{
407
408 if (!badShape.IsNull()) return Standard_False;
409
410 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
411
412 // On met tous les edges et les vertex des faces modifiees
413 TopoDS_Face F;
414 TopoDS_Edge E;
415 TopoDS_Vertex V;
416 TopExp_Explorer editer;
417 TopExp_Explorer vtiter;
418
419 while (itf.More()) {
420 const TopoDS_Face& Fc = itf.Key();
421
422 // Exploration of the edges of the face
423 editer.Init(Fc,TopAbs_EDGE);
424 while (editer.More()) {
425 E = TopoDS::Edge(editer.Current());
426
427 if (!myEMap.IsBound(E)) {
428 Draft_EdgeInfo EInf(Standard_True);
429 myEMap.Bind(E,EInf);
430 }
431 myEMap(E).Add(Fc);
432
433 // Exploration of the vertices of the edge
434 vtiter.Init(E,TopAbs_VERTEX);
435 while (vtiter.More()) {
436 V = TopoDS::Vertex(vtiter.Current());
437 if (!myVMap.IsBound(V)) {
438 Draft_VertexInfo VInf;
439 myVMap.Bind(V,VInf);
440 }
441
442 myVMap(V).Add(E);
443 myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
444 vtiter.Next();
445 }
446 editer.Next();
447 }
448 itf.Next();
449 }
450
451
452 TopExp_Explorer anc;
453 Standard_Boolean found;
454
455 // On met les edges contenant les vertex modifies.
456
457 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
458
459 while (itv.More()) {
460 const TopoDS_Vertex& Vt = itv.Key();
461
462 // Exploration of the ancestors of the vertex
463 anc.Init(myShape,TopAbs_EDGE);
464
465 while (anc.More()) {
466 E = TopoDS::Edge(anc.Current());
467 vtiter.Init(E,TopAbs_VERTEX);
468 found = Standard_False;
469 while (vtiter.More()) {
470 if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
471 found = Standard_True;
472 break;
473 }
474 vtiter.Next();
475 }
476 if (found) {
477 if (!myEMap.IsBound(E)) {
478 Draft_EdgeInfo EInf(Standard_False);
479 myEMap.Bind(E,EInf);
480 }
481 myVMap(Vt).Add(E);
482 myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
483 }
484 anc.Next();
485 }
486 itv.Next();
487 }
488
489
490 // On met les faces contenant des edges modifiees
491
492 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
493
494 while (ite.More()) {
495 const TopoDS_Edge& Ed = ite.Key();
496 TopTools_ListIteratorOfListOfShape it;
497 for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
498 F = TopoDS::Face(it.Value());
499 if (!myFMap.IsBound(F)) {
500 TopLoc_Location L;
501 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
502 Handle(Geom_Surface) NewS =
503 Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
504
505 const Handle(Standard_Type)& typs = S->DynamicType();
506 if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
507 typs == STANDARD_TYPE(Geom_ConicalSurface)) {
508 Standard_Real umin,umax,vmin,vmax;
509 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
510 if (!Precision::IsNegativeInfinite(vmin) &&
511 !Precision::IsPositiveInfinite(vmax)) {
512 Standard_Real deltav = 10.*(vmax-vmin);
513 vmin = vmin - deltav;
514 vmax = vmax + deltav;
515 NewS =
516 new Geom_RectangularTrimmedSurface(NewS,0.,2.*PI,vmin,vmax);
517 }
518 }
519
520 Draft_FaceInfo FInf(NewS,Standard_False);
521 myFMap.Bind(F,FInf);
522 }
523 myEMap(Ed).Add(F);
524 }
525 ite.Next();
526 }
527
528 // JAG. On essaie de rajouter des faces pour les bords libres...
529 // JAG 09.11.95
530 ite.Initialize(myEMap);
531 for (; ite.More(); ite.Next()) {
532 Draft_EdgeInfo& Einf = myEMap(ite.Key());
533 if (Einf.NewGeometry() && Einf.Geometry().IsNull() &&
534 Einf.SecondFace().IsNull()) {
535
536 TopLoc_Location Loc;
537 Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
538 S1 = Handle(Geom_Surface)::
539 DownCast(S1->Transformed(Loc.Transformation()));
540 Handle(Geom_Surface) S2;
541
542 Standard_Real f,l;
543 Handle(Geom_Curve) C = BRep_Tool::Curve(ite.Key(),Loc,f,l);
544 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
545 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
546 C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
547 }
548 if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
549 if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
550 gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
551 S2 = new Geom_Plane(thePl);
552 }
553 else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
554 gp_Ax1 axis;
555 if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
556 axis = Handle(Geom_ElementarySurface)::DownCast
557 (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
558 BasisSurface())->Axis();
559 }
560 else {
561 axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
562 }
563 gp_Vec they(axis.Location(), C->Value(0.));
564 gp_Dir axz(axis.Direction().Crossed(they));
565 S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
566
567 }
568 else {
569 badShape = TopoDS::Edge(ite.Key());
570 errStat = Draft_EdgeRecomputation;
571 break; // on sort du for
572 }
573 }
574 else { // on est sur un plan
575 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo anewitv(myVMap);
576 while (anewitv.More()) {
577 Draft_VertexInfo& Vinf = myVMap(anewitv.Key());
578 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
579 if (Vinf.Edge().IsSame(ite.Key())) {
580 break;
581 }
582 }
583 if (Vinf.MoreEdge()) {
584 for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
585 const TopoDS_Edge& edg = Vinf.Edge();
586 if (!edg.IsSame(ite.Key())) {
587 if (!myEMap(edg).FirstFace().IsSame(Einf.FirstFace()) &&
588 (myEMap(edg).SecondFace().IsNull() ||
589 !myEMap(edg).SecondFace().IsSame(Einf.FirstFace()))) {
590 break;
591 }
592 }
593 }
594 if (Vinf.MoreEdge()) {
595 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
596 Handle(GeomAdaptor_HCurve) HCur;
597 gp_Vec Direc;
598 C2 = Handle(Geom_Curve)::DownCast
599 (C2->Transformed(Loc.Transformation()));
600 if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
601 C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
602 }
603 if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
604 Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
605 HCur = new GeomAdaptor_HCurve(C2);
606
607 }
608 else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
609 Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
610 HCur = new GeomAdaptor_HCurve(C);
611 }
612 else {
613 badShape = TopoDS::Edge(ite.Key());
614 errStat = Draft_EdgeRecomputation;
615 break; // on sort de while
616 }
617 Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
618 switch(SLE.GetType()){
619
620 case GeomAbs_Plane :
621 {
622 S2 = new Geom_Plane(SLE.Plane());
623 }
624 break;
625 case GeomAbs_Cylinder :
626 {
627 S2 = new Geom_CylindricalSurface(SLE.Cylinder());
628 }
629 break;
630 default :
631 {
632 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
633 Curve(),
634 Direc);
635 }
636 break;
637 }
638
639 }
640 else {
641 badShape = TopoDS::Edge(ite.Key());
642 errStat = Draft_EdgeRecomputation;
643 break; // on sort du while
644 }
645 break;
646 }
647 anewitv.Next();
648 }
649 }
650
651 if (badShape.IsNull()) {
652 BRep_Builder B;
653 TopoDS_Face TheNewFace;
654 B.MakeFace(TheNewFace,S2,Precision::Confusion());
655 Einf.Add(TheNewFace);
656 Draft_FaceInfo FI(S2,Standard_False);
657 myFMap.Bind(TheNewFace,FI);
658 }
659 else {
660 break; // on sort du for
661 }
662 // Fin JAG 09.11.95
663 }
664 }
665 return (badShape.IsNull());
666}
667
668
669
670
671//=======================================================================
672//function : Perform
673//purpose :
674//=======================================================================
675
676void Draft_Modification::Perform ()
677{
678 if (!badShape.IsNull()) Standard_ConstructionError::Raise();
679
680 if (!myComp) {
681 myComp = Standard_True;
682 if (!Propagate()) {
683 return;
684 }
685
686 // On calcule les faces eventuelles
687
688 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
689 while (itf.More()) {
690 Draft_FaceInfo& Finf = myFMap(itf.Key());
691 if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
692 const TopoDS_Face& F1 = Finf.FirstFace();
693 const TopoDS_Face& F2 = Finf.SecondFace();
694
695 if (F1.IsNull() || F2.IsNull()) {
696 errStat = Draft_FaceRecomputation;
697 badShape = TopoDS::Face(itf.Key());
698 return;
699 }
700 Handle(Geom_Surface) S1 = myFMap(F1).Geometry();
701 Handle(Geom_Surface) S2 = myFMap(F2).Geometry();
702 if (S1.IsNull() || S2.IsNull()) {
703 errStat = Draft_FaceRecomputation;
704 badShape = TopoDS::Face(itf.Key());
705 return;
706 }
707 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
708 S1 = Handle(Geom_RectangularTrimmedSurface)::
709 DownCast(S1)->BasisSurface();
710 }
711 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
712 S2 = Handle(Geom_RectangularTrimmedSurface)::
713 DownCast(S2)->BasisSurface();
714 }
715 Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
716 Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
717 if (P1.IsNull() || P2.IsNull()) {
718 errStat = Draft_FaceRecomputation;
719 badShape = TopoDS::Face(itf.Key());
720 return;
721 }
722 gp_Pln pp1 = P1->Pln();
723 gp_Pln pp2 = P2->Pln();
724 IntAna_QuadQuadGeo i2p(pp1,pp2,
725 Precision::Angular(),Precision::Confusion());
726 if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
727 errStat = Draft_FaceRecomputation;
728 badShape = TopoDS::Face(itf.Key());
729 return;
730 }
731
732 gp_Dir extrdir = i2p.Line(1).Direction();
733
734 // On garde le meme sens que la face de base
735 Handle(Geom_Surface) RefSurf =
736 BRep_Tool::Surface(TopoDS::Face(itf.Key()));
737 if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
738 RefSurf =
739 Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
740 ->BasisSurface();
741 }
742 gp_Dir DirRef;
743
744 if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
745 gp_Ax3 AxeRef =
746 Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
747 ->Cylinder().Position();
748 DirRef = AxeRef.Direction();
749 }
750 else if (RefSurf->DynamicType() ==
751 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
752 DirRef =
753 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
754 ->Direction();
755 }
756
757 if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
758
759 // on peut ameliorer la rapidite en stockant l`info lors de
760 // InternalAdd --> modif de FaceInfo pour garder le cercle
761
762 Handle(Geom_Circle) CCir =
763 Handle(Geom_Circle)::DownCast(Finf.Curve());
764 Handle(Geom_Surface) NewS =
765 new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);
766
767 Standard_Real umin, umax, vmin, vmax;
768 BRepTools::UVBounds(TopoDS::Face(itf.Key()),umin,umax,vmin,vmax);
769 if (!Precision::IsNegativeInfinite(vmin) &&
770 !Precision::IsPositiveInfinite(vmax)) {
771 Standard_Real deltav = 2.*(vmax-vmin);
772 vmin = vmin - deltav;
773 vmax = vmax + deltav;
774 }
775
776 // tres temporaire
777 else {
778 vmax = 300;
779 vmin = -300;
780 }
781
782 NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*PI,vmin,vmax);
783 Finf.ChangeGeometry() = NewS;
784 }
785 itf.Next();
786 }
787
788 // On calcule les nouveaux edges.
789
790 Handle(Geom_Surface) S1,S2;
791 Handle(Geom_Curve) C, newC;
792 Standard_Real f,l;
793 TopLoc_Location L;
794 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
795
796 while (ite.More()) {
797 Draft_EdgeInfo& Einf = myEMap(ite.Key());
798
799 const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
800
801 C = BRep_Tool::Curve(theEdge,L,f,l);
802 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
803
804 if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
805 gp_Pnt ptfixe;
806 if (!Einf.IsTangent(ptfixe)) {
807 const TopoDS_Face& FirstFace = Einf.FirstFace();
808 const TopoDS_Face& SecondFace = Einf.SecondFace();
809
810 S1 = myFMap(FirstFace).Geometry();
811 S2 = myFMap(SecondFace).Geometry();
812
813 Standard_Integer detrompeur = 0;
814
815 // On recupere le FirstVertex et la tangente en ce point.
816 TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
817 TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
818 Standard_Real pmin = 0.;
819 Standard_Real prmfv = BRep_Tool::Parameter(FV,ite.Key());
820 Standard_Real prmlv = BRep_Tool::Parameter(LV,ite.Key());
821 gp_Pnt pfv, plv;
822 gp_Vec d1fv,d1lv, newd1;
823 C->D1(prmfv,pfv,d1fv);
824 C->D1(prmlv,plv,d1lv);
825
826 Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
827 Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
828
829 //On passe la tolerance de la face pour projeter
830 GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
831 GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
832 GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
833 GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
834
835 if (proj1.IsDone () && proj2.IsDone ()) {
836 if(proj1.LowerDistance()<= Precision::Confusion() &&
837 proj2.LowerDistance()<= Precision::Confusion()) {
838 detrompeur = 1;
839 }
840 }
841
842 if (proj3.IsDone () && proj4.IsDone ()) {
843 if(proj3.LowerDistance() <= Precision::Confusion() &&
844 proj4.LowerDistance() <= Precision::Confusion()) {
845 detrompeur = 2;
846 }
847 }
848
849 gp_Dir TheDirExtr;
850 gp_Ax3 Axis;
851 Handle(Geom_Curve) TheNewCurve;
852 Standard_Boolean KPart = Standard_False;
853
854 if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
855 S1 = Handle(Geom_RectangularTrimmedSurface)::
856 DownCast(S1)->BasisSurface();
857 }
858 if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
859 S2 = Handle(Geom_RectangularTrimmedSurface)::
860 DownCast(S2)->BasisSurface();
861 }
862
863 Standard_Boolean PC1 = Standard_True; // KPart sur S1
864 if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
865 S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
866 KPart = Standard_True;
867 Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
868 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
869 DownCast(S1)->BasisCurve();
870 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
871 DownCast(S1)->Direction();
872 }
873 else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
874 S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
875 KPart = Standard_True;
876 PC1 = Standard_False;
877 Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
878 TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
879 DownCast(S2)->BasisCurve();
880 TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
881 DownCast(S2)->Direction();
882 }
883 Handle(Geom_Circle) aCirc ;
884 if ( KPart) { // TRES Provisoire sur les cercles !!!
885 aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
886 if (aCirc.IsNull())
887 KPart = Standard_False;
888 else
889 {
890 gp_Dir AxofCirc = aCirc->Position().Direction();
891 if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
892 KPart = Standard_True;
893 else
894 KPart = Standard_False;
895 }
896 }
897
898 Standard_Integer imin;
899 GeomInt_IntSS i2s;
900 if ( KPart) {
901 //calcul direct de NewC
902 Standard_Real aLocalReal =
903 gp_Vec(aCirc->Circ().Location(),Axis.Location()).
904 Dot(Axis.Direction());
905 Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
906 gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
907 newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
908 // on sait calculer la PCurve
909 Handle(Geom2d_Line) L2d
910 = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
911 gp::DX2d());
912
913 if ( PC1)
914 Einf.ChangeFirstPC() = L2d;
915 else
916 Einf.ChangeSecondPC() = L2d;
917 }
918 else {
919 S1 = myFMap(Einf.FirstFace()).Geometry();
920 S2 = myFMap(Einf.SecondFace()).Geometry();
921
922 // rem : dub 16/09/97
923 // On ne calcule plus les PCurves tout de suite et pour 2 raisons:
924 // 1 - Si ProjLib doit faire une Approx, c'est idiot d'approximer
925 // toute la courbe d'intersection.
926 // 2 - De plus, si YaRev, on risque de ne plus etre SameRange.
927 i2s.Perform(S1,S2,Precision::Confusion(),
928 Standard_True,Standard_False,Standard_False);
929
930 if (!i2s.IsDone() || i2s.NbLines() <= 0) {
931 errStat = Draft_EdgeRecomputation;
932 badShape = TopoDS::Edge(ite.Key());
933 return;
934 }
935
936 Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
937 GeomAdaptor_Curve TheCurve;
938
939 Standard_Integer i,j; //,jmin;
940
941 if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
942 {
943 imin = 0;
944 for (i=1; i<= i2s.NbLines(); i++) {
945 TheCurve.Load(i2s.Line(i));
946 Extrema_ExtPC myExtPC(pfv,TheCurve);
947
948 Standard_Real locpmin = 0.;
949 if (myExtPC.IsDone()) {
950 if(myExtPC.NbExt() >= 1) {
951 Dist2Min = myExtPC.SquareDistance(1);
952 locpmin = myExtPC.Point(1).Parameter();
953 }
954 if(myExtPC.NbExt() == 2 && Dist2Min > Precision::Confusion() * Precision::Confusion()) {
955 //pour ne pas se tromper dans le choix d'image
956 //du premier vertex de l'edge initial
957 Standard_Real d1_2 = myExtPC.SquareDistance(1);
958 Standard_Real d2_2 = myExtPC.SquareDistance(2);
959 if(d1_2 > 1.21*d2_2) {
960 Dist2Min = myExtPC.SquareDistance(2);
961 locpmin = myExtPC.Point(2).Parameter();
962 }
963 else if(d2_2 > 1.21*d1_2) {
964 Dist2Min = myExtPC.SquareDistance(1);
965 locpmin = myExtPC.Point(1).Parameter();
966 }
967 else {
968 Standard_Real pfvpar = myExtPC.Point(1).Parameter();
969 Standard_Real plvpar = myExtPC.Point(2).Parameter();
970 newC = i2s.Line(i);
971
972 gp_Pnt pfvprim, plvprim;
973
974 newC->D0(pfvpar,pfvprim);
975 newC->D0(plvpar,plvprim);
976
977 Handle(Geom_Surface) theSurf;
978 if(detrompeur == 1) {
979 if(S1->DynamicType() ==
980 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
981 S1 = Handle(Geom_RectangularTrimmedSurface)::
982 DownCast(S1)->BasisSurface();
983 theSurf = S1;
984
985 }
986 else if(detrompeur == 2) {
987 if(S2->DynamicType() ==
988 STANDARD_TYPE(Geom_RectangularTrimmedSurface))
989 S2 = Handle(Geom_RectangularTrimmedSurface)::
990 DownCast(S2)->BasisSurface();
991 theSurf = S2;
992 }
993 if(detrompeur != 0 && detrompeur != 4) {
994 Standard_Real ul, vl, uf, vf;
995 Standard_Real ufprim, ulprim, vfprim, vlprim;
996
997 if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
998 gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
999 ElSLib::Parameters(pl, plv, ul, vl);
1000 ElSLib::Parameters(pl, pfv, uf, vf);
1001 ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
1002 ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
1003 }
1004 else if(theSurf->DynamicType() ==
1005 STANDARD_TYPE(Geom_CylindricalSurface)) {
1006 gp_Cylinder cy = Handle(Geom_CylindricalSurface)
1007 ::DownCast(S2)->Cylinder();
1008 ElSLib::Parameters(cy, plv, ul, vl);
1009 ElSLib::Parameters(cy, pfv, uf, vf);
1010 ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
1011 ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
1012 }
1013 else detrompeur = 4;
1014
1015 if(detrompeur == 1 || detrompeur == 2) {
1016 gp_Vec2d v1((ul-ufprim), (vl-vfprim));
1017 gp_Vec2d norm((vf-vfprim), (ufprim-uf));
1018 gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
1019 if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
1020 Dist2Min = myExtPC.SquareDistance(2);
1021 locpmin = myExtPC.Point(2).Parameter();
1022 }
1023 }
1024 }
1025 }
1026 }
1027 if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
1028 Dist2Min = myExtPC.SquareDistance(1);
1029 locpmin = myExtPC.Point(1).Parameter();
1030 for (j=2; j<=myExtPC.NbExt(); j++) {
1031 Dist2 = myExtPC.SquareDistance(j);
1032 if (Dist2 < Dist2Min) {
1033 Dist2Min = Dist2;
1034 locpmin = myExtPC.Point(j).Parameter();
1035 }
1036 }
1037 }
1038 else if(myExtPC.NbExt() < 1){
1039 Standard_Real dist1_2,dist2_2;
1040 gp_Pnt p1b,p2b;
1041 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1042 if (dist1_2 < dist2_2) {
1043 Dist2Min = dist1_2;
1044 locpmin = TheCurve.FirstParameter();
1045 }
1046 else {
1047 Dist2Min = dist2_2;
1048 locpmin = TheCurve.LastParameter();
1049 }
1050 }
1051
1052 if (Dist2Min < Glob2Min) {
1053 Glob2Min = Dist2Min;
1054 imin = i;
1055 pmin = locpmin;
1056 }
1057 }
1058 }
1059 if (imin == 0) {
1060 errStat = Draft_EdgeRecomputation;
1061 badShape = TopoDS::Edge(ite.Key());
1062 return;
1063 }
1064
1065 newC = i2s.Line(imin);
1066
1067 newC->D1(pmin,pfv,newd1);
1068 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1069
1070 if (YaRev)
1071 newC->Reverse();
1072
1073 if (i2s.HasLineOnS1(imin)) {
1074 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1075 if ( YaRev)
1076 Einf.ChangeFirstPC()->Reverse();
1077 }
1078
1079 if (i2s.HasLineOnS2(imin)) {
1080 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1081 if ( YaRev)
1082 Einf.ChangeSecondPC()->Reverse();
1083 }
1084 } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
1085 else // i2s.Line(1) is BSplineCurve
1086 {
1087 //Find the first curve to glue
1088 TColGeom_SequenceOfCurve Candidates;
1089 if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
1090 S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
1091 {
1092 for (i = 1; i <= i2s.NbLines(); i++)
1093 {
1094 Handle( Geom_Curve ) aCurve = i2s.Line(i);
1095 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1096 GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
1097 Standard_Real U, V;
1098 projector.LowerDistanceParameters( U, V );
1099 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*PI) <= Precision::Confusion())
1100 Candidates.Append( aCurve );
1101 else
1102 {
1103 Pnt = aCurve->Value( aCurve->LastParameter() );
1104 projector.Init( Pnt, S1, Precision::Confusion() );
1105 projector.LowerDistanceParameters( U, V );
1106 if (Abs(U) <= Precision::Confusion() || Abs(U-2.*PI) <= Precision::Confusion())
1107 {
1108 aCurve->Reverse();
1109 Candidates.Append( aCurve );
1110 }
1111 }
1112 }
1113
1114 if(Candidates.Length() == 0)
1115 {
1116// errStat = Draft_EdgeRecomputation;
1117// badShape = TopoDS::Edge(ite.Key());
1118// return;
1119 for (i = 1; i <= i2s.NbLines(); i++)
1120 Candidates.Append( i2s.Line(i) );
1121 }
1122 }
1123 else
1124 {
1125 for (i = 1; i <= i2s.NbLines(); i++)
1126 Candidates.Append( i2s.Line(i) );
1127 }
1128
1129 Handle( Geom_Curve ) FirstCurve;
1130 if (Candidates.Length() > 1)
1131 {
1132 Dist2Min = RealLast();
1133 for (i = 1; i <= Candidates.Length(); i++)
1134 {
1135 Handle( Geom_Curve ) aCurve = Candidates(i);
1136 gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
1137 Dist2 = Pnt.SquareDistance( pfv );
1138 if (Dist2 < Dist2Min)
1139 {
1140 Dist2Min = Dist2;
1141 FirstCurve = aCurve;
1142 }
1143 }
1144 }
1145 else
1146 FirstCurve = Candidates(1);
1147
1148 //Glueing
1149 TColGeom_SequenceOfCurve Curves;
1150 for (i = 1; i <= i2s.NbLines(); i++)
1151 if (FirstCurve != i2s.Line(i))
1152 Curves.Append( i2s.Line(i) );
1153
1154 TColGeom_SequenceOfCurve ToGlue;
1155 gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
1156 Standard_Boolean added = Standard_True;
1157 while (added)
1158 {
1159 added = Standard_False;
1160 for (i = 1; i <= Curves.Length(); i++)
1161 {
1162 Handle( Geom_Curve ) aCurve = Curves(i);
1163 gp_Pnt pfirst, plast;
1164 pfirst = aCurve->Value( aCurve->FirstParameter() );
1165 plast = aCurve->Value( aCurve->LastParameter() );
1166 if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
1167 {
1168 ToGlue.Append( aCurve );
1169 EndPoint = plast;
1170 Curves.Remove(i);
1171 added = Standard_True;
1172 break;
1173 }
1174 if (plast.Distance( EndPoint ) <= Precision::Confusion())
1175 {
1176 aCurve->Reverse();
1177 ToGlue.Append( aCurve );
1178 EndPoint = pfirst;
1179 Curves.Remove(i);
1180 added = Standard_True;
1181 break;
1182 }
1183 }
1184 }
1185
1186 if (FirstCurve.IsNull()) {
1187 errStat = Draft_EdgeRecomputation;
1188 badShape = TopoDS::Edge(ite.Key());
1189 return;
1190 }
1191
1192 GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
1193 for (i = 1; i <= ToGlue.Length(); i++)
1194 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
1195
1196 newC = Concat.BSplineCurve();
1197
1198 TheCurve.Load( newC );
1199 Extrema_ExtPC myExtPC( pfv, TheCurve );
1200 Dist2Min = RealLast();
1201 for (i = 1; i <= myExtPC.NbExt(); i++)
1202 {
1203 Dist2 = myExtPC.SquareDistance(i);
1204 if (Dist2 < Dist2Min)
1205 {
1206 Dist2Min = Dist2;
1207 pmin = myExtPC.Point(i).Parameter();
1208 }
1209 }
1210
1211 newC->D1(pmin,pfv,newd1);
1212 Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.;
1213
1214 if (YaRev)
1215 newC->Reverse();
1216 /*
1217 if (i2s.HasLineOnS1(imin)) {
1218 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
1219 if ( YaRev)
1220 Einf.ChangeFirstPC()->Reverse();
1221 }
1222
1223 if (i2s.HasLineOnS2(imin)) {
1224 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
1225 if ( YaRev)
1226 Einf.ChangeSecondPC()->Reverse();
1227 }
1228 */
1229 } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
1230
1231 Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
1232 } // Fin pas KPart
1233 }
1234 else { // cas de tangence
1235 const TopoDS_Face& F1 = Einf.FirstFace();
1236 const TopoDS_Face& F2 = Einf.SecondFace();
1237
1238 Handle(Geom_Surface) aLocalS1 = myFMap(F1).Geometry();
1239 Handle(Geom_Surface) aLocalS2 = myFMap(F2).Geometry();
1240 if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
1241 errStat = Draft_EdgeRecomputation;
1242 badShape = TopoDS::Edge(ite.Key());
1243 return;
1244 }
1245 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1246 aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
1247 DownCast(aLocalS1)->BasisSurface();
1248 }
1249 if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1250 aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
1251 DownCast(aLocalS2)->BasisSurface();
1252 }
1253
1254 gp_Dir dirextr;
1255 //Standard_Boolean dirfound = Standard_False;
1256 if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1257 gp_Cylinder cyl =
1258 Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
1259 dirextr = cyl.Axis().Direction();
1260 //dirfound = Standard_True;
1261 // voir sens...
1262
1263 }
1264 else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1265 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1266 DownCast(aLocalS1)->Direction();
1267 //dirfound = Standard_True;
1268 // voir sens...
1269
1270 // Ici on sait calculer la PCurve.
1271 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1272 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
1273 Handle(Geom_Circle) GCir =
1274 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1275 if ( !GCir.IsNull()) {
1276 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1277 Handle(Geom2d_Line) PC1 =
1278 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1279 Einf.ChangeFirstPC() = PC1;
1280 }
1281 }
1282
1283 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1284 gp_Cylinder cyl =
1285 Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
1286 dirextr = cyl.Axis().Direction();
1287 //dirfound = Standard_True;
1288 // voir sens...
1289
1290 }
1291 else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
1292 dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
1293 DownCast(aLocalS2)->Direction();
1294 //dirfound = Standard_True;
1295 // voir sens...
1296
1297 // Ici on sait calculer la PCurve.
1298 Handle(Geom_SurfaceOfLinearExtrusion) SEL =
1299 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
1300 Handle(Geom_Circle) GCir =
1301 Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
1302 if ( !GCir.IsNull()) {
1303 Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
1304 Handle(Geom2d_Line) PC2 =
1305 new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
1306 Einf.ChangeSecondPC() = PC2;
1307 }
1308 }
1309 newC = new Geom_Line(ptfixe,dirextr);
1310
1311 gp_Pnt pfv;
1312 gp_Vec d1fv,newd1;
1313 C->D1(0.,pfv,d1fv);
1314 newC->D1(0.,pfv,newd1);
1315 Standard_Boolean YaRev = d1fv.Dot(newd1) <0.;
1316 if (YaRev) {
1317 newC->Reverse();
1318 if(!Einf.FirstPC().IsNull()) {
1319 Einf.ChangeFirstPC()->Reverse();
1320 }
1321 if(!Einf.SecondPC().IsNull()) {
1322 Einf.ChangeSecondPC()->Reverse();
1323 }
1324 }
1325 }
1326
1327 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
1328 if (!T.IsNull()) newC = T->BasisCurve();
1329 Einf.ChangeGeometry() = newC;
1330 }
1331 else if (!Einf.NewGeometry()){
1332 // on met la courbe 3d existante
1333 Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
1334 if (!T.IsNull()) C = T->BasisCurve();
1335 Einf.ChangeGeometry() = C;
1336 }
1337 ite.Next();
1338 }
1339
1340 // On calcule les nouveaux vertex.
1341
1342 Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
1343
1344 Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve;
1345 Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
1346
1347 while (itv.More()) {
1348 GeomAdaptor_Curve AC;
1349 GeomAdaptor_Surface AS;
1350
1351 Draft_VertexInfo& Vinf = myVMap(itv.Key());
1352 if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
1353
1354// pas d'edge concourante => alignement de deux edges consecutives.
1355 gp_Pnt pvt;
1356 Vinf.ChangeGeometry() = pvt;
1357 Vinf.InitEdgeIterator();
1358 if (Vinf.MoreEdge()) {
1359 const TopoDS_Edge& Edg1 = Vinf.Edge();
1360 //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1361 Draft_EdgeInfo& Einf1 = myEMap(Edg1);
1362 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1363 //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
1364 GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
1365 pvt = Projector.NearestPoint();
1366
1367#ifdef DEB
1368 static Standard_Integer VertexRecomp = 1;
1369 if (VertexRecomp!=0) {
1370 cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
1371 cout << " Edg 1 :" << Vinf.Parameter(Edg1) << endl;
1372 cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
1373 }
1374#endif
1375
1376 Standard_Real dion=pvt.SquareDistance(vtori);
1377 Vinf.NextEdge();
1378 if (Vinf.MoreEdge()) {
1379 const TopoDS_Edge& Edg2 = Vinf.Edge();
1380 //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1381 Draft_EdgeInfo& Einf2 = myEMap(Edg2);
1382// Standard_Real f;
1383 gp_Pnt opvt;
1384 Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
1385
1386#ifdef DEB
1387 if (VertexRecomp!=0) {
1388 cout << " Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
1389 cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
1390 }
1391#endif
1392
1393 if (opvt.SquareDistance(vtori) < dion) {
1394 pvt = opvt;
1395 }
1396 //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
1397 Standard_Integer done;
1398 Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
1399 if (done != 0)
1400 {
1401 S1 = myFMap(Einf2.FirstFace()).Geometry();
1402 S2 = myFMap(Einf2.SecondFace()).Geometry();
1403 Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
1404 }
1405 else
1406 Vinf.ChangeParameter(Edg2) = param;
1407 }
1408
1409 Vinf.ChangeGeometry() = pvt;
1410 //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
1411 Standard_Integer done;
1412 Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
1413 if (done != 0)
1414 {
1415 S1 = myFMap(Einf1.FirstFace()).Geometry();
1416 S2 = myFMap(Einf1.SecondFace()).Geometry();
1417 Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
1418 }
1419 else
1420 Vinf.ChangeParameter(Edg1) = param;
1421 itv.Next();
1422 continue;
1423 }
1424
1425
1426 errStat = Draft_VertexRecomputation;
1427 badShape = TopoDS::Vertex(itv.Key());
1428 return;
1429 }
1430
1431 IntCurveSurface_HInter myintcs;
1432 HAC->Set(AC);
1433 HAS->Set(AS);
1434 myintcs.Perform(HAC,HAS);
1435
1436 if (!myintcs.IsDone()) {
1437 errStat = Draft_VertexRecomputation;
1438 badShape = TopoDS::Vertex(itv.Key());
1439 return;
1440 }
1441
1442 gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
1443 gp_Pnt pvt;
1444
1445 Standard_Integer nbsol = myintcs.NbPoints();
1446 if (nbsol <= 0)
1447 {
1448 Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
1449
1450 if(!extr.IsDone() || extr.NbExt() == 0) {
1451 errStat = Draft_VertexRecomputation;
1452 badShape = TopoDS::Vertex(itv.Key());
1453 return;
1454 }
1455
1456
1457 Standard_Real disref = RealLast();
1458 Standard_Integer iref = 0;
1459 Extrema_POnCurv Pc;
1460 Extrema_POnSurf Ps;
1461 for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
1462 {
1463 extr.Points( i, Pc, Ps );
1464 Standard_Real distemp = Pc.Value().SquareDistance(vtori);
1465 if ( distemp < disref)
1466 {
1467 disref = distemp;
1468 iref = i;
1469 }
1470 }
1471 extr.Points( iref, Pc, Ps );
1472 pvt = Pc.Value();
1473 }
1474 else
1475 {
1476 Standard_Real disref = RealLast();
1477 Standard_Integer iref = 0;
1478 for (Standard_Integer i = 1; i <= nbsol; i++)
1479 {
1480 Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
1481 if ( distemp < disref)
1482 {
1483 disref = distemp;
1484 iref = i;
1485 }
1486 }
1487 pvt = myintcs.Point(iref).Pnt();
1488 }
1489
1490 Vinf.ChangeGeometry() = pvt;
1491
1492 for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
1493 const TopoDS_Edge& Edg = Vinf.Edge();
1494 //const Draft_EdgeInfo& Einf = myEMap(Edg);
1495 Draft_EdgeInfo& Einf = myEMap(Edg);
1496 //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
1497 Standard_Integer done;
1498 Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
1499 if (done != 0)
1500 {
1501 S1 = myFMap(Einf.FirstFace()).Geometry();
1502 S2 = myFMap(Einf.SecondFace()).Geometry();
1503 Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
1504 }
1505 else
1506 Vinf.ChangeParameter(Edg) = param;
1507 }
1508 itv.Next();
1509 }
1510 }
1511
1512 // petite boucle de validation/protection
1513
1514 for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
1515 ite.More(); ite.Next()) {
1516 const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
1517
1518 TopoDS_Vertex Vf,Vl;
1519 TopExp::Vertices(edg,Vf,Vl);
1520 if (edg.Orientation() == TopAbs_REVERSED) {
1521 Vf.Reverse();
1522 Vl.Reverse();
1523 }
1524 Standard_Real pf,pl,tolerance;
1525 if (!NewParameter(Vf,edg,pf,tolerance)) {
1526 pf = BRep_Tool::Parameter(Vf,edg);
1527 }
1528 if (!NewParameter(Vl,edg,pl,tolerance)) {
1529 pl = BRep_Tool::Parameter(Vl,edg);
1530 }
1531 if (pl <= pf) {
1532// const Handle(Geom_Curve) gc=ite.Value().Geometry();
1533// if (!gc.IsNull()) {
1534// pl = gc->LastParameter();
1535// pf = gc->FirstParameter();
1536// }
1537 Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
1538 if (theCurve->IsClosed())
1539 {
1540 // pf >= pl
1541 Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
1542 Standard_Real pconf = Precision::PConfusion();
1543 if (Abs( pf - LastPar ) <= pconf)
1544 pf = FirstPar;
1545 else if (Abs( pl - FirstPar ) <= pconf)
1546 pl = LastPar;
1547
1548 if(pl <= pf) {
1549 pl += (LastPar-FirstPar);
1550 }
1551
1552 }
1553 if (pl <= pf) {
1554 errStat = Draft_EdgeRecomputation;
1555 badShape = TopoDS::Edge(ite.Key());
1556 return;
1557 }
1558 }
1559 if (myVMap.IsBound( Vf ))
1560 myVMap(Vf).ChangeParameter(edg) = pf;
1561 if (myVMap.IsBound( Vl ))
1562 myVMap(Vl).ChangeParameter(edg) = pl;
1563 }
1564}
1565
1566
1567
1568//=======================================================================
1569//function : NewSurface
1570//purpose :
1571//=======================================================================
1572
1573Handle(Geom_Surface) Draft_Modification::NewSurface
1574 (const Handle(Geom_Surface)& S,
1575 const TopAbs_Orientation Oris,
1576 const gp_Dir& Direction,
1577 const Standard_Real Angle,
1578 const gp_Pln& NeutralPlane)
1579{
1580 Handle(Geom_Surface) NewS;
1581
1582 Handle(Standard_Type) TypeS = S->DynamicType();
1583
1584 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1585 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1586 gp_Ax1 Axe;
1587 Standard_Real Theta;
1588 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1589 if ( Abs(Theta) > Precision::Angular()) {
1590 NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
1591 }
1592 else {
1593 NewS = S;
1594 }
1595 }
1596 }
1597 else if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1598 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1599 if (Abs(testdir) <= 1.-Precision::Angular()) {
1600#ifdef DEB
1601 cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
1602#endif
1603 return NewS;
1604 }
1605 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1606 testdir = Direction.Dot(Cy.Axis().Direction());
1607 if (Abs(testdir) <= 1.-Precision::Angular()) {
1608#ifdef DEB
1609 cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
1610#endif
1611 return NewS;
1612 }
1613 if (Abs(Angle) > Precision::Angular()) {
1614 IntAna_QuadQuadGeo i2s;
1615 i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
1616 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1617#ifdef DEB
1618 cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
1619#endif
1620 return NewS;
1621 }
1622 gp_Ax3 axcone = Cy.Position();
1623 // Pb : Ou est la matiere???
1624 Standard_Real alpha = Angle;
1625 Standard_Boolean direct(axcone.Direct());
1626 if ((direct && Oris == TopAbs_REVERSED) ||
1627 (!direct && Oris == TopAbs_FORWARD)) {
1628 alpha = -alpha;
1629 }
1630
1631 gp_Pnt Center = i2s.Circle(1).Location();
1632 if (testdir <0.) {
1633 alpha = -alpha;
1634 }
1635 Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
1636 Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
1637 if (Rad < 0.) {
1638 Rad = -Rad;
1639 }
1640 else {
1641 alpha = -alpha;
1642 }
1643 gp_Cone co(axcone,alpha,Rad);
1644 NewS = new Geom_ConicalSurface(co);
1645 }
1646 else {
1647 NewS = S;
1648 }
1649 }
1650 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1651
1652 Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
1653 if (Abs(testdir) <= 1.-Precision::Angular()) {
1654#ifdef DEB
1655 cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
1656#endif
1657 return NewS;
1658 }
1659
1660 gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1661
1662 testdir = Direction.Dot(Co1.Axis().Direction());
1663 if (Abs(testdir) <= 1.-Precision::Angular()) {
1664#ifdef DEB
1665 cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
1666#endif
1667 return NewS;
1668 }
1669
1670
1671 IntAna_QuadQuadGeo i2s;
1672 i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
1673 if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
1674#ifdef DEB
1675 cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
1676#endif
1677 return NewS;
1678 }
1679 gp_Ax3 axcone = Co1.Position();
1680 // Pb : Ou est la matiere???
1681 Standard_Real alpha = Angle;
1682 Standard_Boolean direct(axcone.Direct());
1683 if ((direct && Oris == TopAbs_REVERSED) ||
1684 (!direct && Oris == TopAbs_FORWARD)) {
1685 alpha = -alpha;
1686 }
1687
1688 gp_Pnt Center = i2s.Circle(1).Location();
1689 if (Abs(Angle) > Precision::Angular()) {
1690 if (testdir <0.) {
1691 alpha = -alpha;
1692 }
1693 Standard_Real Z = ElCLib::LineParameter(Co1.Axis(),Center);
1694 Standard_Real Rad = i2s.Circle(1).Radius()+Z*Tan(alpha);
1695 if (Rad < 0.) {
1696 Rad = -Rad;
1697 }
1698 else {
1699 alpha = -alpha;
1700 }
1701 if (Abs(alpha-Co1.SemiAngle()) < Precision::Angular()) {
1702 NewS = S;
1703 }
1704 else {
1705 gp_Cone co(axcone,alpha,Rad);
1706 NewS = new Geom_ConicalSurface(co);
1707 }
1708 }
1709 else {
1710 NewS = new
1711 Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
1712 }
1713 }
1714 else {
1715#ifdef DEB
1716 cout << "NewSurface:Draft_SurfNotYetImplemented" << endl;
1717#endif
1718 }
1719 return NewS;
1720}
1721
1722
1723//=======================================================================
1724//function : NewCurve
1725//purpose :
1726//=======================================================================
1727
1728Handle(Geom_Curve) Draft_Modification::NewCurve
1729 (const Handle(Geom_Curve)& C,
1730 const Handle(Geom_Surface)& S,
1731 const TopAbs_Orientation Oris,
1732 const gp_Dir& Direction,
1733 const Standard_Real Angle,
1734 const gp_Pln& NeutralPlane,
1735 const Standard_Boolean )
1736
1737{
1738 Handle(Geom_Curve) NewC;
1739
1740 Handle(Standard_Type) TypeS = S->DynamicType();
1741
1742 if (TypeS == STANDARD_TYPE(Geom_Plane)) {
1743 gp_Pln Pl = Handle(Geom_Plane)::DownCast(S)->Pln();
1744 gp_Ax1 Axe;
1745 Standard_Real Theta;
1746 if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
1747 if ( Abs(Theta) > Precision::Angular()) {
1748 NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
1749 }
1750 else {
1751 NewC = C;
1752 }
1753 }
1754 return NewC;
1755 }
1756
1757
1758 if (C->DynamicType() != STANDARD_TYPE(Geom_Line)) {
1759 return NewC;
1760 }
1761
1762
1763 gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
1764// Standard_Real testdir = Direction.Dot(lin.Direction());
1765// if (Abs(testdir) <= 1.-Precision::Angular()) {
1766// return NewC;
1767// }
1768 gp_Dir Norm;
1769 if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
1770 Standard_Real U,V;
1771 gp_Vec d1u,d1v;
1772 gp_Pnt pbid;
1773 gp_Cylinder Cy = Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
1774 ElSLib::Parameters(Cy,lin.Location(),U,V);
1775 ElSLib::D1(U,V,Cy,pbid,d1u,d1v);
1776 Norm = d1u.Crossed(d1v);
1777 }
1778 else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
1779 Standard_Real U,V;
1780 gp_Vec d1u,d1v;
1781 gp_Pnt pbid;
1782 gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
1783 ElSLib::Parameters(Co,lin.Location(),U,V);
1784 ElSLib::D1(U,V,Co,pbid,d1u,d1v);
1785 Norm = d1u.Crossed(d1v);
1786 }
1787
1788 IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
1789 if (ilipl.IsDone() && ilipl.NbPoints() != 0){
1790 if (Oris == TopAbs_REVERSED) {
1791 Norm.Reverse();
1792 }
1793 gp_Ax1 axrot(ilipl.Point(1), Norm.Crossed(Direction));
1794 gp_Lin lires = gp_Lin(gp_Ax1(ilipl.Point(1),Direction)).
1795 Rotated(axrot,Angle);
1796 if (lires.Direction().Dot(lin.Direction()) < 0.) {
1797 lires.Reverse();
1798 }
1799 NewC = new Geom_Line(lires);
1800 }
1801 return NewC;
1802}
1803
1804
1805//=======================================================================
1806//function : Choose
1807//purpose :
1808//=======================================================================
1809
1810static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
1811 Draft_DataMapOfEdgeEdgeInfo& theEMap,
1812 const TopoDS_Vertex& Vtx,
1813 Draft_VertexInfo& Vinf,
1814 GeomAdaptor_Curve& AC,
1815 GeomAdaptor_Surface& AS)
1816{
1817 gp_Vec tgref;
1818 Vinf.InitEdgeIterator();
1819
1820 // On cherche un edge de regularite ou dont SecondFace est nulle
1821 while (Vinf.MoreEdge()) {
1822 const TopoDS_Edge& E1 = Vinf.Edge();
1823 const Draft_EdgeInfo& Einf1 = theEMap(E1);
1824 if (Einf1.SecondFace().IsNull()) {
1825 break;
1826 }
1827 else {
1828 GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
1829 Einf1.SecondFace());
1830 if (te >= GeomAbs_G1) {
1831 break;
1832 }
1833 }
1834 Vinf.NextEdge();
1835 }
1836 if (!Vinf.MoreEdge()) { // on prend le premier edge
1837 Vinf.InitEdgeIterator();
1838 }
1839
1840 const TopoDS_Edge& Eref = Vinf.Edge();
1841 //const Draft_EdgeInfo& Einf = theEMap(Eref);
1842 Draft_EdgeInfo& Einf = theEMap(Eref);
1843
1844 AC.Load(Einf.Geometry());
1845
1846 Standard_Real f,l,prm;
1847 TopLoc_Location Loc;
1848 Handle(Geom_Curve) C = BRep_Tool::Curve(Eref,Loc,f,l);
1849 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1850 gp_Pnt ptbid;
1851 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1852 Standard_Integer done;
1853 Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
1854 if (done != 0)
1855 {
1856 Handle( Geom_Surface ) S1 = theFMap(Einf.FirstFace()).Geometry();
1857 Handle( Geom_Surface ) S2 = theFMap(Einf.SecondFace()).Geometry();
1858 prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
1859 }
1860 else
1861 prm = param;
1862 C->D1(prm,ptbid,tgref);
1863
1864
1865 Vinf.InitEdgeIterator();
1866 while (Vinf.MoreEdge()) {
1867 // On cherche un edge non tangent
1868 const TopoDS_Edge& Edg = Vinf.Edge();
1869 if (!Edg.IsSame(Eref)) {
1870 //const Draft_EdgeInfo& Einfo = theEMap(Edg);
1871 Draft_EdgeInfo& Einfo = theEMap(Edg);
1872 if (!Einfo.SecondFace().IsNull() &&
1873 BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace())
1874 <= GeomAbs_C0) {
1875 C = BRep_Tool::Curve(Edg,Loc,f,l);
1876 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
1877 //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
1878 Standard_Integer anewdone;
1879 Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
1880 if (anewdone != 0)
1881 {
1882 Handle( Geom_Surface ) S1 = theFMap(Einfo.FirstFace()).Geometry();
1883 Handle( Geom_Surface ) S2 = theFMap(Einfo.SecondFace()).Geometry();
1884 prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
1885 }
1886 else
1887 prm = anewparam;
1888 gp_Vec tg;
1889 C->D1(prm,ptbid,tg);
1890 if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
1891 break;
1892 }
1893 }
1894 }
1895 Vinf.NextEdge();
1896 }
1897 if (!Vinf.MoreEdge()) {
1898 return Standard_False;
1899 }
1900
1901 const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
1902 if (!Einf.SecondFace().IsNull()) {
1903
1904 if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
1905 Einf2.FirstFace().IsSame(Einf.SecondFace())) {
1906 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1907 }
1908 else {
1909 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1910 }
1911 }
1912 else {
1913 if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
1914 AS.Load(theFMap(Einf2.SecondFace()).Geometry());
1915 }
1916 else {
1917 AS.Load(theFMap(Einf2.FirstFace()).Geometry());
1918 }
1919 }
1920 return Standard_True;
1921}
1922
1923
1924//=======================================================================
1925//function : Parameter
1926//purpose :
1927//=======================================================================
1928
1929static Standard_Real Parameter(const Handle(Geom_Curve)& C,
1930 const gp_Pnt& P,
1931 Standard_Integer& done)
1932{
1933 done = 0;
1934 Handle(Geom_Curve) cbase = C;
1935 Handle(Standard_Type) ctyp = C->DynamicType();
1936 if (ctyp == STANDARD_TYPE(Geom_TrimmedCurve)) {
1937 cbase = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
1938 ctyp = cbase->DynamicType();
1939 }
1940 Standard_Real param;
1941 if (ctyp == STANDARD_TYPE(Geom_Line)) {
1942 param = ElCLib::Parameter(Handle(Geom_Line)::DownCast(cbase)->Lin(),P);
1943 }
1944 else if (ctyp == STANDARD_TYPE(Geom_Circle)) {
1945 param = ElCLib::Parameter(Handle(Geom_Circle)::DownCast(cbase)->Circ(),P);
1946 if (Abs(2.*PI-param) <=Epsilon(2.*PI)) {
1947 param = 0.;
1948 }
1949 }
1950 else if (ctyp == STANDARD_TYPE(Geom_Ellipse)) {
1951 param = ElCLib::Parameter(Handle(Geom_Ellipse)::DownCast(cbase)->Elips(),P);
1952 if (Abs(2.*PI-param) <=Epsilon(2.*PI)) {
1953 param = 0.;
1954 }
1955 }
1956 else if (ctyp == STANDARD_TYPE(Geom_Parabola)) {
1957 param = ElCLib::Parameter(Handle(Geom_Parabola)::DownCast(cbase)->Parab(),P);
1958 }
1959 else if (ctyp == STANDARD_TYPE(Geom_Hyperbola)) {
1960 param = ElCLib::Parameter(Handle(Geom_Hyperbola)::DownCast(cbase)->Hypr(),P);
1961 }
1962 else {
1963 GeomAdaptor_Curve TheCurve(C);
1964 Extrema_ExtPC myExtPC(P,TheCurve);
1965 if (!myExtPC.IsDone()) {
1966 Standard_Failure::Raise();
1967 }
1968 if (myExtPC.NbExt() >= 1) {
1969 Standard_Real Dist2, Dist2Min = myExtPC.SquareDistance(1);
1970 Standard_Integer j, jmin = 1;
1971 for (j = 2; j <= myExtPC.NbExt(); j++) {
1972 Dist2 = myExtPC.SquareDistance(j);
1973 if (Dist2 < Dist2Min) {
1974 Dist2Min = Dist2;
1975 jmin = j;
1976 }
1977 }
1978 param = myExtPC.Point(jmin).Parameter();
1979 }
1980 else {
1981 Standard_Real dist1_2,dist2_2;
1982 gp_Pnt p1b,p2b;
1983 myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
1984 if (dist1_2 < dist2_2) {
1985 done = -1;
1986 param = TheCurve.FirstParameter();
1987 }
1988 else {
1989 done = 1;
1990 param = TheCurve.LastParameter();
1991 }
1992 }
1993
1994 if (cbase->IsPeriodic()) {
1995 Standard_Real Per = cbase->Period();
1996 Standard_Real Tolp = Precision::Parametric(Precision::Confusion());
1997 if (Abs(Per-param) <= Tolp) {
1998 param = 0.;
1999 }
2000 }
2001 }
2002 return param;
2003}
2004
2005//=======================================================================
2006//function : SmartParameter
2007//purpose :
2008//=======================================================================
2009
2010static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
2011 const Standard_Real EdgeTol,
2012 const gp_Pnt& Pnt,
2013 const Standard_Integer sign,
2014 const Handle(Geom_Surface)& S1,
2015 const Handle(Geom_Surface)& S2)
2016{
2017 Handle( Geom2d_Curve ) NewC2d;
2018 Standard_Real Tol = Precision::Confusion();
2019 Standard_Real Etol = EdgeTol;
2020
2021 Handle( Geom2d_Curve ) pcu1 = Einf.FirstPC();
2022 Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
2023
2024 if (pcu1.IsNull())
2025 {
2026 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2027 pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
2028 Einf.ChangeFirstPC() = pcu1;
2029 }
2030 if (pcu2.IsNull())
2031 {
2032 Handle( Geom_Curve ) theCurve = Einf.Geometry();
2033 pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
2034 Einf.ChangeSecondPC() = pcu2;
2035 }
2036
2037 GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
2038 Standard_Real U, V;
2039 Projector.LowerDistanceParameters( U, V );
2040
2041 NewC2d = Einf.FirstPC();
2042 if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
2043 NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
2044
2045 gp_Pnt2d P2d( U, V );
2046 Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
2047 if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
2048 {
2049 Handle( Geom2d_BSplineCurve ) BCurve;
2050 if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
2051 BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
2052 else
2053 BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
2054 if (sign == -1)
2055 {
2056 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2057 PntArray(1) = P2d;
2058 PntArray(2) = BCurve->Pole(1);
2059 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2060 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2061 Concat.Add( Patch, Tol, Standard_False );
2062 BCurve = Concat.BSplineCurve();
2063 }
2064 else
2065 {
2066 TColgp_Array1OfPnt2d PntArray( 1, 2 );
2067 PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
2068 PntArray(2) = P2d;
2069 Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
2070 Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
2071 Concat.Add( Patch, Tol, Standard_True );
2072 BCurve = Concat.BSplineCurve();
2073 }
2074 NewC2d = BCurve;
2075 }
2076 Einf.ChangeFirstPC() = NewC2d;
2077 Handle( Geom2dAdaptor_HCurve ) hcur = new Geom2dAdaptor_HCurve( NewC2d );
2078 Handle( GeomAdaptor_HSurface ) hsur = new GeomAdaptor_HSurface( S1 );
2079 Adaptor3d_CurveOnSurface cons( hcur, hsur );
2080 Handle( Adaptor3d_HCurveOnSurface ) hcons = new Adaptor3d_HCurveOnSurface( cons );
2081 Handle( GeomAdaptor_HSurface ) hsur2 = new GeomAdaptor_HSurface( S2 );
2082 ProjLib_CompProjectedCurve ProjCurve( hsur2, hcons, Tol, Tol );
2083 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
2084 HProjector->Set( ProjCurve );
2085 Standard_Real Udeb, Ufin;
2086 ProjCurve.Bounds(1, Udeb, Ufin);
2087 Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
2088 Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
2089 GeomAbs_C1, 10, MaxSeg,
2090 Standard_False, Standard_False );
2091 Einf.ChangeSecondPC() = appr.Curve2d();
2092 Einf.ChangeGeometry() = appr.Curve3d();
2093 Einf.SetNewGeometry( Standard_True );
2094
2095 if (sign == -1)
2096 return Einf.Geometry()->FirstParameter();
2097 else
2098 return Einf.Geometry()->LastParameter();
2099
2100}
2101
2102//=======================================================================
2103//function : Orientation
2104//purpose :
2105//=======================================================================
2106
2107static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
2108 const TopoDS_Face& F)
2109{
2110//
2111// changement portage NT
2112//
2113 TopExp_Explorer expl ;
2114 expl.Init(S,
2115 TopAbs_FACE) ;
2116 while (expl.More()) {
2117 if (TopoDS::Face(expl.Current()).IsSame(F)) {
2118 return expl.Current().Orientation();
2119 }
2120 expl.Next();
2121 }
2122 return TopAbs_FORWARD;
2123}
2124
2125
2126//=======================================================================
2127//function : FindRotation
2128//purpose :
2129//=======================================================================
2130
2131static Standard_Boolean FindRotation(const gp_Pln& Pl,
2132 const TopAbs_Orientation Oris,
2133 const gp_Dir& Direction,
2134 const Standard_Real Angle,
2135 const gp_Pln& NeutralPlane,
2136 gp_Ax1& Axe,
2137 Standard_Real& theta)
2138{
2139 IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
2140 Precision::Angular(),Precision::Confusion());
2141
2142 if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
2143 gp_Lin li = i2pl.Line(1);
2144 // On va essayer de tourner autour de cette ligne
2145 gp_Dir nx = li.Direction();
2146 gp_Dir ny = Pl.Axis().Direction().Crossed(nx);
2147 Standard_Real a = Direction.Dot(nx);
2148 if (Abs(a) <=1-Precision::Angular()) {
2149 Standard_Real b = Direction.Dot(ny);
2150 Standard_Real c = Direction.Dot(Pl.Axis().Direction());
2151 Standard_Boolean direct(Pl.Position().Direct());
2152 if ((direct && Oris == TopAbs_REVERSED) ||
2153 (!direct && Oris == TopAbs_FORWARD)) {
2154 b = -b;
2155 c = -c;
2156 }
2157 Standard_Real denom = Sqrt(1-a*a);
2158 Standard_Real Sina = Sin(Angle);
2159 if (denom>Abs(Sina)) {
2160 Standard_Real phi = ATan2(b/denom,c/denom);
2161 Standard_Real theta0 = ACos(Sina/denom);
2162 theta = theta0 - phi;
2163 if (Cos(theta) <0.) {
2164 theta = -theta0 -phi;
2165 }
2166 // modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
2167 while (Abs(theta)>PI) {
2168 theta = theta + PI*(theta<0 ? 1 : -1);
2169 }
2170 // modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
2171 Axe = li.Position();
2172 return Standard_True;
2173 }
2174 }
2175 }
2176 return Standard_False;
2177}
2178