1 // Created on: 1997-05-05
2 // Created by: Jerome LEMONIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <GeomPlate_BuildPlateSurface.hxx>
19 #include <Adaptor2d_Curve2d.hxx>
20 #include <Adaptor3d_Curve.hxx>
21 #include <Adaptor3d_CurveOnSurface.hxx>
22 #include <Approx_CurveOnSurface.hxx>
23 #include <Extrema_ExtPS.hxx>
24 #include <Extrema_POnSurf.hxx>
25 #include <GCPnts_AbscissaPoint.hxx>
26 #include <Geom2d_BezierCurve.hxx>
27 #include <Geom2d_BSplineCurve.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2dAdaptor_Curve.hxx>
30 #include <Geom2dInt_GInter.hxx>
31 #include <Geom_BSplineSurface.hxx>
32 #include <Geom_Plane.hxx>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_Surface.hxx>
35 #include <GeomAdaptor.hxx>
36 #include <GeomAdaptor_Surface.hxx>
37 #include <GeomLProp_SLProps.hxx>
38 #include <GeomPlate_BuildAveragePlane.hxx>
39 #include <GeomPlate_CurveConstraint.hxx>
40 #include <GeomPlate_HArray1OfSequenceOfReal.hxx>
41 #include <GeomPlate_MakeApprox.hxx>
42 #include <GeomPlate_PointConstraint.hxx>
43 #include <GeomPlate_SequenceOfAij.hxx>
44 #include <GeomPlate_Surface.hxx>
46 #include <gp_Pnt2d.hxx>
48 #include <gp_Vec2d.hxx>
49 #include <IntRes2d_IntersectionPoint.hxx>
50 #include <Law_Interpol.hxx>
51 #include <LocalAnalysis_SurfaceContinuity.hxx>
52 #include <Plate_D2.hxx>
53 #include <Plate_FreeGtoCConstraint.hxx>
54 #include <Plate_GtoCConstraint.hxx>
55 #include <Plate_PinpointConstraint.hxx>
56 #include <Plate_Plate.hxx>
57 #include <Precision.hxx>
58 #include <ProjLib_HCompProjectedCurve.hxx>
59 #include <Standard_ConstructionError.hxx>
60 #include <TColgp_Array1OfPnt2d.hxx>
61 #include <TColgp_HArray1OfPnt.hxx>
62 #include <TColgp_SequenceOfVec.hxx>
63 #include <TColStd_HArray1OfReal.hxx>
64 #include <TColStd_SequenceOfInteger.hxx>
65 #include <Message_ProgressScope.hxx>
70 #include <DrawTrSurf.hxx>
71 #include <Draw_Marker3D.hxx>
72 #include <Draw_Marker2D.hxx>
75 // 1 : Display of Geometries and intermediary control
76 // 2 : Display of the number of constraints by curve + Intersection
77 // 3 : Dump of constraints in Plate
78 static Standard_Integer NbPlan = 0;
79 //static Standard_Integer NbCurv2d = 0;
80 static Standard_Integer NbMark = 0;
81 static Standard_Integer NbProj = 0;
85 #include <OSD_Chronometer.hxx>
86 #include <Geom_Surface.hxx>
87 static Standard_Integer Affich=0;
90 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
91 // =========================================================
92 // C O N S T R U C T O R S
93 // =========================================================
94 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
96 //---------------------------------------------------------
97 // Constructor compatible with the old version
98 //---------------------------------------------------------
99 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
100 const Handle(TColStd_HArray1OfInteger)& NPoints,
101 const Handle(GeomPlate_HArray1OfHCurve)& TabCurve,
102 const Handle(TColStd_HArray1OfInteger)& Tang,
103 const Standard_Integer Degree,
104 const Standard_Integer NbIter,
105 const Standard_Real Tol2d,
106 const Standard_Real Tol3d,
107 const Standard_Real TolAng,
108 const Standard_Real ,
109 const Standard_Boolean Anisotropie
111 myAnisotropie(Anisotropie),
119 { Standard_Integer NTCurve=TabCurve->Length();// Number of linear constraints
120 myNbPtsOnCur = 0; // Different calculation of the number of points depending on the length
121 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
122 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
124 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
127 throw Standard_ConstructionError("GeomPlate : the bounds Array is null");
128 if (Tang->Length()==0)
129 throw Standard_ConstructionError("GeomPlate : the constraints Array is null");
130 Standard_Integer nbp = 0;
132 for ( i=1;i<=NTCurve;i++)
133 { nbp+=NPoints->Value(i);
136 throw Standard_ConstructionError("GeomPlate : the resolution is impossible if the number of constraints points is 0");
138 throw Standard_ConstructionError("GeomPlate ; the degree resolution must be upper of 2");
139 // Filling fields passing from the old constructor to the new one
140 for(i=1;i<=NTCurve;i++)
141 { Handle(GeomPlate_CurveConstraint) Cont = new GeomPlate_CurveConstraint
142 ( TabCurve->Value(i),
145 myLinCont->Append(Cont);
147 mySurfInitIsGive=Standard_False;
149 myIsLinear = Standard_True;
150 myFree = Standard_False;
153 //------------------------------------------------------------------
154 // Constructor with initial surface and degree
155 //------------------------------------------------------------------
156 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
157 const Handle(Geom_Surface)& Surf,
158 const Standard_Integer Degree,
159 const Standard_Integer NbPtsOnCur,
160 const Standard_Integer NbIter,
161 const Standard_Real Tol2d,
162 const Standard_Real Tol3d,
163 const Standard_Real TolAng,
164 const Standard_Real /*TolCurv*/,
165 const Standard_Boolean Anisotropie ) :
167 myAnisotropie(Anisotropie),
169 myNbPtsOnCur(NbPtsOnCur),
177 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
179 throw Standard_ConstructionError("GeomPlate : the degree must be above 2");
180 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
181 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
182 mySurfInitIsGive=Standard_True;
184 myIsLinear = Standard_True;
185 myFree = Standard_False;
189 //---------------------------------------------------------
190 // Constructor with degree
191 //---------------------------------------------------------
192 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
193 const Standard_Integer Degree,
194 const Standard_Integer NbPtsOnCur,
195 const Standard_Integer NbIter,
196 const Standard_Real Tol2d,
197 const Standard_Real Tol3d,
198 const Standard_Real TolAng,
199 const Standard_Real /*TolCurv*/,
200 const Standard_Boolean Anisotropie ) :
201 myAnisotropie(Anisotropie),
203 myNbPtsOnCur(NbPtsOnCur),
211 throw Standard_ConstructionError("GeomPlate : Number of iteration must be >= 1");
213 throw Standard_ConstructionError("GeomPlate : the degree resolution must be upper of 2");
214 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
215 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
216 mySurfInitIsGive=Standard_False;
218 myIsLinear = Standard_True;
219 myFree = Standard_False;
222 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
223 // =========================================================
224 // P U B L I C M E T H O D S
225 // =========================================================
226 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
230 //-------------------------------------------------------------------------
231 // Function : TrierTab, internal Function, does not belong to class
232 //-------------------------------------------------------------------------
233 // Reorder the table of transformations
234 // After the call of CourbeJointive the order of curves is modified
235 // Ex : initial order of curves ==> A B C D E F
236 // In TabInit we note ==> 1 2 3 4 5 6
237 // after CourbeJointive ==> A E C B D F
238 // TabInit ==> 1 5 3 2 4 6
239 // after TrierTab the Table contains ==> 1 4 3 5 2 6
240 // It is also possible to access the 2nd curve by taking TabInit[2]
241 // i.e. the 4th from the table of classified curves
242 //-------------------------------------------------------------------------
243 static void TrierTab(Handle(TColStd_HArray1OfInteger)& Tab)
245 // Parse the table of transformations to find the initial order
246 Standard_Integer Nb=Tab->Length();
247 TColStd_Array1OfInteger TabTri(1,Nb);
248 for (Standard_Integer i=1;i<=Nb;i++)
249 TabTri.SetValue(Tab->Value(i),i);
250 Tab->ChangeArray1()=TabTri;
253 //---------------------------------------------------------
254 // Function : ProjectCurve
255 //---------------------------------------------------------
256 Handle(Geom2d_Curve) GeomPlate_BuildPlateSurface::ProjectCurve(const Handle(Adaptor3d_Curve)& Curv)
258 // Project a curve on a plane
259 Handle(Geom2d_Curve) Curve2d ;
260 Handle(GeomAdaptor_Surface) hsur = new GeomAdaptor_Surface(mySurfInit);
263 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (hsur, Curv, myTol3d/10, myTol3d/10);
265 Standard_Real UdebCheck, UfinCheck, ProjUdeb, ProjUfin;
266 UdebCheck = Curv->FirstParameter();
267 UfinCheck = Curv->LastParameter();
268 HProjector->Bounds( 1, ProjUdeb, ProjUfin );
270 if (HProjector->NbCurves() != 1 ||
271 Abs( UdebCheck -ProjUdeb ) > Precision::PConfusion() ||
272 Abs( UfinCheck -ProjUfin ) > Precision::PConfusion())
274 if (HProjector->IsSinglePnt(1, P2d))
276 // solution in a point
277 TColgp_Array1OfPnt2d poles(1, 2);
279 Curve2d = new (Geom2d_BezierCurve) (poles);
283 Curve2d.Nullify(); // No continuous solution
285 std::cout << "BuildPlateSurace :: No continuous projection" << std::endl;
290 GeomAbs_Shape Continuity = GeomAbs_C1;
291 Standard_Integer MaxDegree = 10, MaxSeg;
292 Standard_Real Udeb, Ufin;
293 HProjector->Bounds(1, Udeb, Ufin);
295 MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
296 Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d);
297 appr.Perform(MaxSeg, MaxDegree, Continuity, Standard_False, Standard_True);
299 Curve2d = appr.Curve2d();
304 sprintf(name,"proj_%d",++NbProj);
305 DrawTrSurf::Set(name, Curve2d);
310 //---------------------------------------------------------
311 // Function : ProjectedCurve
312 //---------------------------------------------------------
313 Handle(Adaptor2d_Curve2d) GeomPlate_BuildPlateSurface::ProjectedCurve( Handle(Adaptor3d_Curve)& Curv)
315 // Projection of a curve on the initial surface
317 Handle(GeomAdaptor_Surface) hsur = new GeomAdaptor_Surface(mySurfInit);
319 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (hsur, Curv, myTolU/10, myTolV/10);
320 if (HProjector->NbCurves() != 1)
322 HProjector.Nullify(); // No continuous solution
324 std::cout << "BuildPlateSurace :: No continuous projection" << std::endl;
329 Standard_Real First1,Last1,First2,Last2;
330 First1=Curv->FirstParameter();
331 Last1 =Curv->LastParameter();
332 HProjector->Bounds(1,First2,Last2);
334 if (Abs(First1-First2) <= Max(myTolU,myTolV) &&
335 Abs(Last1-Last2) <= Max(myTolU,myTolV))
337 HProjector = Handle(ProjLib_HCompProjectedCurve)::DownCast(HProjector->Trim(First2,Last2,Precision::PConfusion()));
341 HProjector.Nullify(); // No continuous solution
343 std::cout << "BuildPlateSurace :: No complete projection" << std::endl;
350 //---------------------------------------------------------
351 // Function : ProjectPoint
352 //---------------------------------------------------------
353 // Projects a point on the initial surface
354 //---------------------------------------------------------
355 gp_Pnt2d GeomPlate_BuildPlateSurface::ProjectPoint(const gp_Pnt &p3d)
358 Standard_Integer nearest = 1;
359 if( myProj.NbExt() > 1)
361 Standard_Real dist2mini = myProj.SquareDistance(1);
362 for (Standard_Integer i=2; i<=myProj.NbExt();i++)
364 if (myProj.SquareDistance(i) < dist2mini)
366 dist2mini = myProj.SquareDistance(i);
371 P=myProj.Point(nearest);
379 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
380 // =========================================================
381 // P U B L I C M E T H O D S
382 // =========================================================
383 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
384 //---------------------------------------------------------
386 //---------------------------------------------------------
387 // Initializes linear and point constraints
388 //---------------------------------------------------------
389 void GeomPlate_BuildPlateSurface::Init()
390 { myLinCont->Clear();
392 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
393 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
396 //---------------------------------------------------------
397 // Function : LoadInitSurface
398 //---------------------------------------------------------
399 // Loads the initial surface
400 //---------------------------------------------------------
401 void GeomPlate_BuildPlateSurface::LoadInitSurface(const Handle(Geom_Surface)& Surf)
403 mySurfInitIsGive=Standard_True;
406 //---------------------------------------------------------
408 //---------------------------------------------------------
409 //---------------------------------------------------------
410 // Adds a linear constraint
411 //---------------------------------------------------------
412 void GeomPlate_BuildPlateSurface::
413 Add(const Handle(GeomPlate_CurveConstraint)& Cont)
414 { myLinCont->Append(Cont);
417 void GeomPlate_BuildPlateSurface::SetNbBounds( const Standard_Integer NbBounds )
419 myNbBounds = NbBounds;
422 //---------------------------------------------------------
424 //---------------------------------------------------------
425 //---------------------------------------------------------
426 // Adds a point constraint
427 //---------------------------------------------------------
428 void GeomPlate_BuildPlateSurface::
429 Add(const Handle(GeomPlate_PointConstraint)& Cont)
431 myPntCont->Append(Cont);
434 //---------------------------------------------------------
435 // Function : Perform
436 // Calculates the surface filled with loaded constraints
437 //---------------------------------------------------------
438 void GeomPlate_BuildPlateSurface::Perform(const Message_ProgressRange& theProgress)
442 OSD_Chronometer Chrono;
448 myNbBounds = myLinCont->Length();
451 //=====================================================================
452 // Declaration of variables.
453 //=====================================================================
454 Standard_Integer NTLinCont = myLinCont->Length(),
455 NTPntCont = myPntCont->Length(), NbBoucle=0;
456 Standard_Boolean Fini=Standard_True;
457 if ((NTLinCont + NTPntCont) == 0)
460 std::cout << "WARNING : GeomPlate : The number of constraints is null." << std::endl;
466 //======================================================================
468 //======================================================================
469 Message_ProgressScope aPS(theProgress, "Calculating the surface filled", 100, Standard_True);
470 if (!mySurfInitIsGive)
472 ComputeSurfInit (aPS.Next(10));
479 { // Table of transformations to preserve the initial order, see TrierTab
480 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
481 for (Standard_Integer l=1;l<=NTLinCont;l++)
482 myInitOrder->SetValue(l,l);
483 if (!CourbeJointive(myTol3d))
484 {// throw Standard_Failure("Curves are not joined");
486 std::cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<std::endl;
489 TrierTab(myInitOrder); // Reorder the table of transformations
491 else if(NTLinCont > 0)//Patch
493 mySense = new TColStd_HArray1OfInteger( 1, NTLinCont, 0 );
494 myInitOrder = new TColStd_HArray1OfInteger( 1, NTLinCont, 1 );
498 if (mySurfInit.IsNull())
503 Standard_Real u1,v1,u2,v2;
504 mySurfInit->Bounds(u1,v1,u2,v2);
505 GeomAdaptor_Surface aSurfInit(mySurfInit);
506 myTolU = aSurfInit.UResolution(myTol3d);
507 myTolV = aSurfInit.VResolution(myTol3d);
508 myProj.Initialize(aSurfInit,u1,v1,u2,v2,
511 //======================================================================
512 // Projection of curves
513 //======================================================================
514 Standard_Boolean Ok = Standard_True;
515 for (Standard_Integer i = 1; i <= NTLinCont; i++)
516 if(myLinCont->Value(i)->Curve2dOnSurf().IsNull())
518 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
519 if (Curve2d.IsNull())
524 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
528 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
533 mySurfInit = App.Surface();
535 mySurfInit->Bounds(u1,v1,u2,v2);
536 GeomAdaptor_Surface Surf(mySurfInit);
537 myTolU = Surf.UResolution(myTol3d);
538 myTolV = Surf.VResolution(myTol3d);
539 myProj.Initialize(Surf,u1,v1,u2,v2,
543 for (Standard_Integer i = 1; i <= NTLinCont; i++)
545 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
546 if (Curve2d.IsNull())
551 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
555 mySurfInit = myPlanarSurfInit;
557 mySurfInit->Bounds(u1,v1,u2,v2);
558 GeomAdaptor_Surface SurfNew(mySurfInit);
559 myTolU = SurfNew.UResolution(myTol3d);
560 myTolV = SurfNew.VResolution(myTol3d);
561 myProj.Initialize(SurfNew,u1,v1,u2,v2,
564 for (Standard_Integer i = 1; i <= NTLinCont; i++)
565 myLinCont->ChangeValue(i)->
566 SetCurve2dOnSurf(ProjectCurve( myLinCont->Value(i)->Curve3d() ) );
568 else { // Project the points
569 for (Standard_Integer i=1; i<=NTPntCont; i++) {
571 myPntCont->Value(i)->D0(P);
572 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
577 //======================================================================
578 // Projection of points
579 //======================================================================
580 for (Standard_Integer i=1;i<=NTPntCont;i++) {
581 if (! myPntCont->Value(i)->HasPnt2dOnSurf()) {
583 myPntCont->Value(i)->D0(P);
584 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
588 //======================================================================
589 // Number of points by curve
590 //======================================================================
591 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
594 //======================================================================
595 // Management of incompatibilites between curves
596 //======================================================================
597 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
598 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
599 if (NTLinCont != 0) {
600 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
601 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
602 Intersect(PntInter, PntG1G1);
605 //======================================================================
606 // Loop to obtain a better surface
607 //======================================================================
609 myFree = !myIsLinear;
614 if (Affich && NbBoucle) {
615 std::cout<<"Resultats boucle"<< NbBoucle << std::endl;
616 std::cout<<"DistMax="<<myG0Error<<std::endl;
618 std::cout<<"AngleMax="<<myG1Error<<std::endl;
620 std::cout<<"CourbMax="<<myG2Error<<std::endl;
625 { //====================================================================
626 // Calculate the total number of points and the maximum of points by curve
627 //====================================================================
628 Standard_Integer NPointMax=0;
629 for (Standard_Integer i=1;i<=NTLinCont;i++)
630 if ((myLinCont->Value(i)->NbPoints())>NPointMax)
631 NPointMax=(Standard_Integer )( myLinCont->Value(i)->NbPoints());
632 //====================================================================
633 // Discretization of curves
634 //====================================================================
635 Discretise(PntInter, PntG1G1);
636 //====================================================================
637 // Preparation of constraint points for plate
638 //====================================================================
639 LoadCurve( NbBoucle );
640 if ( myPntCont->Length() != 0)
641 LoadPoint( NbBoucle );
642 //====================================================================
643 // Construction of the surface
644 //====================================================================
646 myPlate.SolveTI(myDegree, ComputeAnisotropie(), aPS.Next(90));
653 if (!myPlate.IsDone())
656 std::cout << "WARNING : GeomPlate : calculation of Plate failed" << std::endl;
661 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
662 Standard_Real Umin,Umax,Vmin,Vmax;
663 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
664 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
666 Fini = VerifSurface(NbBoucle);
667 if ((NbBoucle >= myNbIter)&&(!Fini))
670 std::cout<<"Warning: objective was not reached"<<std::endl;
672 Fini = Standard_True;
675 if ((NTPntCont != 0)&&(Fini))
676 { Standard_Real di,an,cu;
677 VerifPoints(di,an,cu);
681 { LoadPoint( NbBoucle );
682 //====================================================================
683 //Construction of the surface
684 //====================================================================
685 myPlate.SolveTI(myDegree, ComputeAnisotropie(), aPS.Next(90));
692 if (!myPlate.IsDone())
695 std::cout << "WARNING : GeomPlate : calculation of Plate failed" << std::endl;
700 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
701 Standard_Real Umin,Umax,Vmin,Vmax;
702 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
703 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
704 Fini = Standard_True;
705 Standard_Real di,an,cu;
706 VerifPoints(di,an,cu);
708 } while (!Fini); // End loop for better surface
711 { std::cout<<"======== Global results ==========="<<std::endl;
712 std::cout<<"DistMax="<<myG0Error<<std::endl;
714 std::cout<<"AngleMax="<<myG1Error<<std::endl;
716 std::cout<<"CourbMax="<<myG2Error<<std::endl;
721 std::cout<<"*** END OF GEOMPLATE ***"<<std::endl;
722 std::cout<<"Time of calculation : "<<Tps<<std::endl;
723 std::cout<<"Number of loops : "<<NbBoucle<<std::endl;
727 //---------------------------------------------------------
728 // Function : EcartContraintesMIL
729 //---------------------------------------------------------
730 void GeomPlate_BuildPlateSurface::
731 EcartContraintesMil ( const Standard_Integer c,
732 Handle(TColStd_HArray1OfReal)& d,
733 Handle(TColStd_HArray1OfReal)& an,
734 Handle(TColStd_HArray1OfReal)& courb)
736 Standard_Integer NbPt=myParCont->Value(c).Length();
741 NbPt=myParCont->Value(c).Length();
742 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
744 gp_Pnt2d P2d;Standard_Integer i;
745 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(c);
746 switch (LinCont->Order())
748 for (i=1; i<NbPt; i++)
749 { U = ( myParCont->Value(c).Value(i) +
750 myParCont->Value(c).Value(i+1) )/2;
752 if (!LinCont->ProjectedCurve().IsNull())
753 P2d = LinCont->ProjectedCurve()->Value(U);
755 { if (!LinCont->Curve2dOnSurf().IsNull())
756 P2d = LinCont->Curve2dOnSurf()->Value(U);
758 P2d = ProjectPoint(Pi);
760 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
763 d->ChangeValue(i) = Pf.Distance(Pi);
767 for (i=1; i<NbPt; i++)
768 { U = ( myParCont->Value(c).Value(i) +
769 myParCont->Value(c).Value(i+1) )/2;
770 LinCont->D1(U, Pi, v1i, v2i);
771 if (!LinCont->ProjectedCurve().IsNull())
772 P2d = LinCont->ProjectedCurve()->Value(U);
774 { if (!LinCont->Curve2dOnSurf().IsNull())
775 P2d = LinCont->Curve2dOnSurf()->Value(U);
777 P2d = ProjectPoint(Pi);
779 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
780 d->ChangeValue(i) = Pf.Distance(Pi);
781 v3i = v1i^v2i; v3f=v1f^v2f;
782 Standard_Real angle=v3f.Angle(v3i);
784 an->ChangeValue(i) = M_PI -angle;
786 an->ChangeValue(i) = angle;
791 Handle(Geom_Surface) Splate (myGeomPlateSurface);
792 LocalAnalysis_SurfaceContinuity CG2;
793 for (i=1; i<NbPt; i++)
794 { U = ( myParCont->Value(c).Value(i) +
795 myParCont->Value(c).Value(i+1) )/2;
797 if (!LinCont->ProjectedCurve().IsNull())
798 P2d = LinCont->ProjectedCurve()->Value(U);
800 { if (!LinCont->Curve2dOnSurf().IsNull())
801 P2d = LinCont->Curve2dOnSurf()->Value(U);
803 P2d = ProjectPoint(Pi);
805 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
807 CG2.ComputeAnalysis(Prop, myLinCont->Value(c)->LPropSurf(U),
809 d->ChangeValue(i)=CG2.C0Value();
810 an->ChangeValue(i)=CG2.G1Angle();
811 courb->ChangeValue(i)=CG2.G2CurvatureGap();
819 //---------------------------------------------------------
820 // Function : Disc2dContour
821 //---------------------------------------------------------
822 void GeomPlate_BuildPlateSurface::
823 Disc2dContour ( const Standard_Integer /*nbp*/,
824 TColgp_SequenceOfXY& Seq2d)
827 if (Seq2d.Length()!=4)
828 std::cout<<"Number of points should be equal to 4 for Disc2dContour"<<std::endl;
833 // sampling in "cosine" + 3 points on each interval
834 Standard_Integer NTCurve = myLinCont->Length();
835 Standard_Integer NTPntCont = myPntCont->Length();
839 Standard_Real u1,v1,u2,v2;
842 mySurfInit->Bounds(u1,v1,u2,v2);
843 GeomAdaptor_Surface Surf(mySurfInit);
844 myProj.Initialize(Surf,u1,v1,u2,v2,
847 for( i=1; i<=NTPntCont; i++)
848 if (myPntCont->Value(i)->Order()!=-1)
849 { P2d = myPntCont->Value(i)->Pnt2dOnSurf();
850 UV.SetX(P2d.Coord(1));
851 UV.SetY(P2d.Coord(2));
854 for(i=1; i<=NTCurve; i++)
856 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(i);
857 if (LinCont->Order()!=-1)
858 { Standard_Integer NbPt=myParCont->Value(i).Length();
859 // first point of constraint (j=0)
860 if (!LinCont->ProjectedCurve().IsNull())
861 P2d = LinCont->ProjectedCurve()->Value(myParCont->Value(i).Value(1));
864 { if (!LinCont->Curve2dOnSurf().IsNull())
865 P2d = LinCont->Curve2dOnSurf()->Value(myParCont->Value(i).Value(1));
869 LinCont->D0(myParCont->Value(i).Value(1),PP);
870 P2d = ProjectPoint(PP);
874 UV.SetX(P2d.Coord(1));
875 UV.SetY(P2d.Coord(2));
877 for (Standard_Integer j=2; j<NbPt; j++)
878 { Standard_Real Uj=myParCont->Value(i).Value(j),
879 Ujp1=myParCont->Value(i).Value(j+1);
880 if (!LinCont->ProjectedCurve().IsNull())
881 P2d = LinCont->ProjectedCurve()->Value((Ujp1+3*Uj)/4);
884 { if (!LinCont->Curve2dOnSurf().IsNull())
885 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+3*Uj)/4);
889 LinCont->D0((Ujp1+3*Uj)/4,PP);
890 P2d = ProjectPoint(PP);
893 UV.SetX(P2d.Coord(1));
894 UV.SetY(P2d.Coord(2));
896 // point 1/2 previous
897 if (!LinCont->ProjectedCurve().IsNull())
898 P2d = LinCont->ProjectedCurve()->Value((Ujp1+Uj)/2);
901 { if (!LinCont->Curve2dOnSurf().IsNull())
902 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+Uj)/2);
906 LinCont->D0((Ujp1+Uj)/2,PP);
907 P2d = ProjectPoint(PP);
911 UV.SetX(P2d.Coord(1));
912 UV.SetY(P2d.Coord(2));
914 // point 3/4 previous
915 if (!LinCont->ProjectedCurve().IsNull())
916 P2d = LinCont->ProjectedCurve()->Value((3*Ujp1+Uj)/4);
919 { if (!LinCont->Curve2dOnSurf().IsNull())
920 P2d = LinCont->Curve2dOnSurf()->Value((3*Ujp1+Uj)/4);
924 LinCont->D0((3*Ujp1+Uj)/4,PP);
925 P2d = ProjectPoint(PP);
929 UV.SetX(P2d.Coord(1));
930 UV.SetY(P2d.Coord(2));
932 // current constraint point
933 if (!LinCont->ProjectedCurve().IsNull())
934 P2d = LinCont->ProjectedCurve()->Value(Ujp1);
937 { if (!LinCont->Curve2dOnSurf().IsNull())
938 P2d = LinCont->Curve2dOnSurf()->Value(Ujp1);
942 LinCont->D0(Ujp1,PP);
943 P2d = ProjectPoint(PP);
947 UV.SetX(P2d.Coord(1));
948 UV.SetY(P2d.Coord(2));
955 //---------------------------------------------------------
956 // Function : Disc3dContour
957 //---------------------------------------------------------
958 void GeomPlate_BuildPlateSurface::
959 Disc3dContour (const Standard_Integer /*nbp*/,
960 const Standard_Integer iordre,
961 TColgp_SequenceOfXYZ& Seq3d)
964 if (Seq3d.Length()!=4)
965 std::cout<<"nbp should be equal to 4 for Disc3dContour"<<std::endl;
966 if (iordre!=0&&iordre!=1)
967 std::cout<<"incorrect order for Disc3dContour"<<std::endl;
971 // sampling in "cosine" + 3 points on each interval
972 Standard_Real u1,v1,u2,v2;
973 mySurfInit->Bounds(u1,v1,u2,v2);
974 GeomAdaptor_Surface Surf(mySurfInit);
975 myProj.Initialize(Surf,u1,v1,u2,v2,
976 Surf.UResolution(myTol3d),
977 Surf.VResolution(myTol3d));
978 Standard_Integer NTCurve = myLinCont->Length();
979 Standard_Integer NTPntCont = myPntCont->Length();
986 for( i=1; i<=NTPntCont; i++)
987 if (myPntCont->Value(i)->Order()!=-1)
989 { myPntCont->Value(i)->D0(P3d);
996 myPntCont->Value(i)->D1(P3d,v1h,v2h);
1005 for(i=1; i<=NTCurve; i++)
1006 if (myLinCont->Value(i)->Order()!=-1)
1008 { Standard_Integer NbPt=myParCont->Value(i).Length();
1009 // first constraint point (j=0)
1010 // Standard_Integer NbPt=myParCont->Length();
1012 myLinCont->Value(i)->D0(myParCont->Value(i).Value(1),P3d);
1019 myLinCont->Value(i)->D1(myParCont->Value(i).Value(1),P3d,v1h,v2h);
1027 for (Standard_Integer j=2; j<NbPt; j++)
1028 { Standard_Real Uj=myParCont->Value(i).Value(j),
1029 Ujp1=myParCont->Value(i).Value(j+1);
1031 // point 1/4 previous
1032 myLinCont->Value(i)->D0((Ujp1+3*Uj)/4,P3d);
1037 // point 1/2 previous
1038 myLinCont->Value(i)->D0((Ujp1+Uj)/2,P3d);
1043 // point 3/4 previous
1044 myLinCont->Value(i)->D0((3*Ujp1+Uj)/4,P3d);
1049 // current constraint point
1050 myLinCont->Value(i)->D0(Ujp1,P3d);
1057 // point 1/4 previous
1058 myLinCont->Value(i)->D1((Ujp1+3*Uj)/4,P3d,v1h,v2h);
1064 // point 1/2 previous
1065 myLinCont->Value(i)->D1((Ujp1+Uj)/2,P3d,v1h,v2h);
1071 // point 3/4 previous
1072 myLinCont->Value(i)->D1((3*Ujp1+Uj)/4,P3d,v1h,v2h);
1078 // current constraint point
1079 myLinCont->Value(i)->D1(Ujp1,P3d,v1h,v2h);
1092 //---------------------------------------------------------
1093 // Function : IsDone
1094 //---------------------------------------------------------
1095 Standard_Boolean GeomPlate_BuildPlateSurface::IsDone() const
1096 { return myPlate.IsDone();
1101 //---------------------------------------------------------
1102 // Function : Surface
1103 //---------------------------------------------------------
1104 Handle(GeomPlate_Surface) GeomPlate_BuildPlateSurface::Surface() const
1105 { return myGeomPlateSurface ;
1108 //---------------------------------------------------------
1109 // Function : SurfInit
1110 //---------------------------------------------------------
1111 Handle(Geom_Surface) GeomPlate_BuildPlateSurface::SurfInit() const
1112 { return mySurfInit ;
1116 //---------------------------------------------------------
1118 //---------------------------------------------------------
1119 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Sense() const
1120 { Standard_Integer NTCurve = myLinCont->Length();
1121 Handle(TColStd_HArray1OfInteger) Sens = new TColStd_HArray1OfInteger(1,
1123 for (Standard_Integer i=1; i<=NTCurve; i++)
1124 Sens->SetValue(i,mySense->Value(myInitOrder->Value(i)));
1130 //---------------------------------------------------------
1131 // Function : Curve2d
1132 //---------------------------------------------------------
1133 Handle(TColGeom2d_HArray1OfCurve) GeomPlate_BuildPlateSurface::Curves2d() const
1134 { Standard_Integer NTCurve = myLinCont->Length();
1135 Handle(TColGeom2d_HArray1OfCurve) C2dfin =
1136 new TColGeom2d_HArray1OfCurve(1,NTCurve);
1138 for (Standard_Integer i=1; i<=NTCurve; i++)
1139 C2dfin->SetValue(i,myLinCont->Value(myInitOrder->Value(i))->Curve2dOnSurf());
1145 //---------------------------------------------------------
1147 //---------------------------------------------------------
1148 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Order() const
1149 { Handle(TColStd_HArray1OfInteger) result=
1150 new TColStd_HArray1OfInteger(1,myLinCont->Length());
1151 for (Standard_Integer i=1;i<=myLinCont->Length();i++)
1152 result->SetValue(myInitOrder->Value(i),i);
1157 //---------------------------------------------------------
1158 // Function : G0Error
1159 //---------------------------------------------------------
1160 Standard_Real GeomPlate_BuildPlateSurface::G0Error() const
1164 //---------------------------------------------------------
1165 // Function : G1Error
1166 //---------------------------------------------------------
1167 Standard_Real GeomPlate_BuildPlateSurface::G1Error() const
1171 //---------------------------------------------------------
1172 // Function : G2Error
1173 //---------------------------------------------------------
1174 Standard_Real GeomPlate_BuildPlateSurface::G2Error() const
1178 //=======================================================================
1179 //function : G0Error
1181 //=======================================================================
1183 Standard_Real GeomPlate_BuildPlateSurface::G0Error( const Standard_Integer Index )
1185 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1186 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1187 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1188 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1189 Standard_Real MaxDistance = 0.;
1190 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1191 if (tdistance->Value(i) > MaxDistance)
1192 MaxDistance = tdistance->Value(i);
1196 //=======================================================================
1197 //function : G1Error
1199 //=======================================================================
1201 Standard_Real GeomPlate_BuildPlateSurface::G1Error( const Standard_Integer Index )
1203 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1204 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1205 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1206 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1207 Standard_Real MaxAngle = 0.;
1208 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1209 if (tangle->Value(i) > MaxAngle)
1210 MaxAngle = tangle->Value(i);
1214 //=======================================================================
1215 //function : G2Error
1217 //=======================================================================
1219 Standard_Real GeomPlate_BuildPlateSurface::G2Error( const Standard_Integer Index )
1221 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1222 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1223 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1224 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1225 Standard_Real MaxCurvature = 0.;
1226 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1227 if (tcurvature->Value(i) > MaxCurvature)
1228 MaxCurvature = tcurvature->Value(i);
1229 return MaxCurvature;
1232 Handle(GeomPlate_CurveConstraint) GeomPlate_BuildPlateSurface::CurveConstraint( const Standard_Integer order) const
1234 return myLinCont->Value(order);
1236 Handle(GeomPlate_PointConstraint) GeomPlate_BuildPlateSurface::PointConstraint( const Standard_Integer order) const
1238 return myPntCont->Value(order);
1240 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1241 // =========================================================
1242 // P R I V A T E M E T H O D S
1243 // =========================================================
1244 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1246 //=======================================================================
1247 // Function : CourbeJointive
1248 // Purpose : Create a chain of curves to calculate the
1249 // initial surface with the method of max flow.
1250 // Return true if it is a closed contour.
1251 //=======================================================================
1253 Standard_Boolean GeomPlate_BuildPlateSurface::
1254 CourbeJointive(const Standard_Real tolerance)
1255 { Standard_Integer nbf = myLinCont->Length();
1256 Standard_Real Ufinal1,Uinit1,Ufinal2,Uinit2;
1257 mySense = new TColStd_HArray1OfInteger(1,nbf,0);
1258 Standard_Boolean result=Standard_True;
1259 Standard_Integer j=1,i;
1262 while (j <= (myNbBounds-1))
1264 Standard_Integer a=0;
1267 { result = Standard_False;
1271 { if (i > myNbBounds)
1272 { result = Standard_False;
1277 Uinit1=myLinCont->Value(j)->FirstParameter();
1278 Ufinal1=myLinCont->Value(j)->LastParameter();
1279 Uinit2=myLinCont->Value(i)->FirstParameter();
1280 Ufinal2=myLinCont->Value(i)->LastParameter();
1281 if (mySense->Value(j)==1)
1283 myLinCont->Value(j)->D0(Ufinal1,P1);
1284 myLinCont->Value(i)->D0(Uinit2,P2);
1285 if (P1.Distance(P2)<tolerance)
1287 Handle(GeomPlate_CurveConstraint) tampon = myLinCont->Value(j+1);
1288 myLinCont->SetValue(j+1,myLinCont->Value(i));
1289 myLinCont->SetValue(i,tampon);
1290 Standard_Integer Tmp=myInitOrder->Value(j+1);
1291 // See function TrierTab for the functioning of myInitOrder
1292 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1293 myInitOrder->SetValue(i,Tmp);
1298 mySense->SetValue(j+1,0);
1302 { myLinCont->Value(i)->D0(Ufinal2,P2);
1304 if (P1.Distance(P2)<tolerance)
1306 Handle(GeomPlate_CurveConstraint) tampon =
1307 myLinCont->Value(j+1);
1308 myLinCont->SetValue(j+1,myLinCont->Value(i));
1309 myLinCont->SetValue(i,tampon);
1310 Standard_Integer Tmp=myInitOrder->Value(j+1);
1311 // See function TrierTab for the functioning of myInitOrder
1312 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1313 myInitOrder->SetValue(i,Tmp);
1316 mySense->SetValue(j+1,1);
1324 Uinit1=myLinCont->Value( myNbBounds )->FirstParameter();
1325 Ufinal1=myLinCont->Value( myNbBounds )->LastParameter();
1326 Uinit2=myLinCont->Value(1)->FirstParameter();
1327 Ufinal2=myLinCont->Value(1)->LastParameter();
1328 myLinCont->Value( myNbBounds )->D0(Ufinal1,P1);
1329 myLinCont->Value(1)->D0(Uinit2,P2);
1330 if ((mySense->Value( myNbBounds )==0)
1331 &&(P1.Distance(P2)<tolerance))
1333 return ((Standard_True)&&(result));
1335 myLinCont->Value( myNbBounds )->D0(Uinit1,P1);
1336 if ((mySense->Value( myNbBounds )==1)
1337 &&(P1.Distance(P2)<tolerance))
1339 return ((Standard_True)&&(result));
1341 else return Standard_False;
1345 //-------------------------------------------------------------------------
1346 // Function : ComputeSurfInit
1347 //-------------------------------------------------------------------------
1348 // Calculate the initial surface either by the method of max flow or by
1349 // the method of the plane of inertia if the contour is not closed or if
1350 // there are point constraints.
1351 //-------------------------------------------------------------------------
1353 void GeomPlate_BuildPlateSurface::ComputeSurfInit(const Message_ProgressRange& theProgress)
1355 Standard_Integer nopt=2, popt=2, Np=1;
1356 Standard_Boolean isHalfSpace = Standard_True;
1357 Standard_Real LinTol = 0.001, AngTol = 0.001; //AngTol = 0.0001; //LinTol = 0.0001
1359 // Option to calculate the initial plane
1360 Standard_Integer NTLinCont = myLinCont->Length(), NTPntCont = myPntCont->Length();
1361 // Table of transformation to preserve the initial order see TrierTab
1362 if (NTLinCont != 0) {
1363 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
1364 for (Standard_Integer i = 1; i <= NTLinCont; i++)
1365 myInitOrder->SetValue( i, i );
1368 Standard_Boolean CourbeJoint = (NTLinCont != 0) && CourbeJointive (myTol3d);
1369 if (CourbeJoint && IsOrderG1())
1372 // Table contains the cloud of points for calculation of the plane
1373 Standard_Integer NbPoint = 20, Discr = NbPoint/4, pnum = 0;
1374 Handle( TColgp_HArray1OfPnt ) Pts = new TColgp_HArray1OfPnt( 1, (NbPoint+1)*NTLinCont+NTPntCont );
1375 TColgp_SequenceOfVec Vecs, NewVecs;
1376 GeomPlate_SequenceOfAij Aset;
1377 Standard_Real Uinit, Ufinal, Uif;
1379 Standard_Integer i ;
1380 for ( i = 1; i <= NTLinCont; i++)
1382 Standard_Integer Order = myLinCont->Value(i)->Order();
1386 Uinit = myLinCont->Value(i)->FirstParameter();
1387 Ufinal = myLinCont->Value(i)->LastParameter();
1388 Uif = Ufinal - Uinit;
1389 if (mySense->Value(i) == 1)
1395 gp_Vec Vec1, Vec2, Normal;
1396 Standard_Boolean ToReverse = Standard_False;
1397 if (i > 1 && Order >= GeomAbs_G1)
1400 myLinCont->Value(i)->D1( Uinit, P, Vec1, Vec2 );
1401 Normal = Vec1 ^ Vec2;
1402 if (LastVec.IsOpposite( Normal, AngTol ))
1403 ToReverse = Standard_True;
1406 for (Standard_Integer j = 0; j <= NbPoint; j++)
1407 { // Number of points per curve = 20
1408 // Linear distribution
1409 Standard_Real Inter = j*Uif/(NbPoint);
1410 if (Order < GeomAbs_G1 || j % Discr != 0)
1411 myLinCont->Value(i)->D0( Uinit+Inter, Pts->ChangeValue(++pnum) );
1414 myLinCont->Value(i)->D1( Uinit+Inter, Pts->ChangeValue(++pnum), Vec1, Vec2 );
1415 Normal = Vec1 ^ Vec2;
1419 Standard_Boolean isNew = Standard_True;
1420 Standard_Integer k ;
1421 for ( k = 1; k <= Vecs.Length(); k++)
1422 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1424 isNew = Standard_False;
1428 for (k = 1; k <= NewVecs.Length(); k++)
1429 if (NewVecs(k).IsEqual( Normal, LinTol, AngTol ))
1431 isNew = Standard_False;
1435 NewVecs.Append( Normal );
1438 if (Order >= GeomAbs_G1)
1440 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1445 } //for (i = 1; i <= NTLinCont; i++)
1449 for (i = 1; i <= NTPntCont; i++)
1451 Standard_Integer Order = myPntCont->Value(i)->Order();
1454 gp_Vec Vec1, Vec2, Normal;
1455 if (Order < GeomAbs_G1)
1456 myPntCont->Value(i)->D0( Pts->ChangeValue(++pnum) );
1459 myPntCont->Value(i)->D1( Pts->ChangeValue(++pnum), Vec1, Vec2 );
1460 Normal = Vec1 ^ Vec2;
1462 Standard_Boolean isNew = Standard_True;
1463 for (Standard_Integer k = 1; k <= Vecs.Length(); k++)
1464 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1466 isNew = Standard_False;
1471 NewVecs.Append( Normal );
1472 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1475 NewVecs(1).Reverse();
1476 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1482 } //for (i = 1; i <= NTPntCont; i++)
1486 Standard_Boolean NullExist = Standard_True;
1489 NullExist = Standard_False;
1490 for (i = 1; i <= Vecs.Length(); i++)
1491 if (Vecs(i).SquareMagnitude() == 0.)
1493 NullExist = Standard_True;
1498 GeomPlate_BuildAveragePlane BAP( Vecs, Pts );
1499 Standard_Real u1,u2,v1,v2;
1500 BAP.MinMaxBox(u1,u2,v1,v2);
1501 // The space is greater for projections
1502 Standard_Real du = u2 - u1;
1503 Standard_Real dv = v2 - v1;
1504 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1505 mySurfInit = new Geom_RectangularTrimmedSurface( BAP.Plane(), u1,u2,v1,v2 );
1507 } //if (isHalfSpace)
1511 std::cout<<std::endl<<"Normals are not in half space"<<std::endl<<std::endl;
1513 myIsLinear = Standard_False;
1516 } //if (NTLinCont != 0 && (CourbeJoint = CourbeJointive( myTol3d )) && IsOrderG1())
1519 TrierTab( myInitOrder ); // Reorder the table of transformations
1523 if ( NTPntCont != 0)
1524 nopt = 1; //Calculate by the method of plane of inertia
1525 else if (!CourbeJoint || NTLinCont != myNbBounds)
1526 {// throw Standard_Failure("Curves are not joined");
1528 std::cout << "WARNING : Curves are non-adjacent with tolerance " << myTol3d << std::endl;
1533 Standard_Real LenT=0;
1534 Standard_Integer Npt=0;
1535 Standard_Integer NTPoint=20*NTLinCont;
1536 Standard_Integer i ;
1537 for ( i=1;i<=NTLinCont;i++)
1538 LenT+=myLinCont->Value(i)->Length();
1539 for (i=1;i<=NTLinCont;i++)
1540 { Standard_Integer NbPoint= (Standard_Integer )( NTPoint*(myLinCont->Value(i)->Length())/LenT);
1544 (void )Npt; // unused but set for debug
1547 // Table containing a cloud of points for calculation of the plane
1548 Handle(TColgp_HArray1OfPnt) Pts = new TColgp_HArray1OfPnt(1,20*NTLinCont+NTPntCont);
1549 Standard_Integer NbPoint=20;
1550 Standard_Real Uinit,Ufinal, Uif;
1551 for ( i=1;i<=NTLinCont;i++)
1552 { Uinit=myLinCont->Value(i)->FirstParameter();
1553 Ufinal=myLinCont->Value(i)->LastParameter();
1555 if (mySense->Value(i) == 1)
1559 for (Standard_Integer j=0; j<NbPoint; j++)
1560 { // Number of points per curve = 20
1561 // Linear distribution
1562 Standard_Real Inter=j*Uif/(NbPoint);
1564 myLinCont->Value(i)->D0(Uinit+Inter,P);
1565 Pts->SetValue(Np++,P);
1568 for (i=1;i<=NTPntCont;i++)
1570 myPntCont->Value(i)->D0(P);
1571 Pts->SetValue(Np++,P);
1575 GeomPlate_BuildAveragePlane BAP( Pts, NbPoint*myNbBounds, myTol3d/1000, popt, nopt );
1579 std::cout << "WARNING : GeomPlate : the initial surface is not a plane." << std::endl;
1584 Standard_Real u1,u2,v1,v2;
1585 BAP.MinMaxBox(u1,u2,v1,v2);
1586 // The space is greater for projections
1587 Standard_Real du = u2 - u1;
1588 Standard_Real dv = v2 - v1;
1589 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1590 mySurfInit = new Geom_RectangularTrimmedSurface(BAP.Plane(),u1,u2,v1,v2);
1593 //Comparing metrics of curves and projected curves
1594 if (NTLinCont != 0 && myIsLinear)
1596 Handle( Geom_Surface ) InitPlane =
1597 (Handle( Geom_RectangularTrimmedSurface )::DownCast(mySurfInit))->BasisSurface();
1599 Standard_Real Ratio = 0., R1 = 2., R2 = 0.6; //R1 = 3, R2 = 0.5;//R1 = 1.4, R2 = 0.8; //R1 = 5., R2 = 0.2;
1600 Handle( GeomAdaptor_Surface ) hsur =
1601 new GeomAdaptor_Surface( InitPlane );
1602 Standard_Integer NbPoint = 20;
1604 // gp_Vec DerC, DerCproj, DU, DV;
1609 for (Standard_Integer i = 1; i <= NTLinCont && myIsLinear; i++)
1611 Standard_Real FirstPar = myLinCont->Value(i)->FirstParameter();
1612 Standard_Real LastPar = myLinCont->Value(i)->LastParameter();
1613 Standard_Real Uif = (LastPar - FirstPar)/(NbPoint);
1615 Handle( Adaptor3d_Curve ) Curve = myLinCont->Value(i)->Curve3d();
1616 Handle( ProjLib_HCompProjectedCurve ) ProjCurve = new ProjLib_HCompProjectedCurve (hsur, Curve, myTol3d, myTol3d);
1617 Adaptor3d_CurveOnSurface AProj(ProjCurve, hsur);
1620 gp_Vec DerC, DerCproj;
1621 for (Standard_Integer j = 1 ; j < NbPoint && myIsLinear; j++)
1623 Standard_Real Inter = FirstPar + j*Uif;
1624 Curve->D1(Inter, P, DerC);
1625 AProj.D1(Inter, P, DerCproj);
1627 Standard_Real A1 = DerC.Magnitude();
1628 Standard_Real A2 = DerCproj.Magnitude();
1635 if (Ratio > R1 || Ratio < R2)
1637 myIsLinear = Standard_False;
1644 std::cout <<"Metrics are too different :"<< Ratio<<std::endl;
1646 // myIsLinear = Standard_True; // !!
1647 } //comparing metrics of curves and projected curves
1652 myPlanarSurfInit = mySurfInit;
1656 sprintf(name,"planinit_%d",NbPlan+1);
1657 DrawTrSurf::Set(name, mySurfInit);
1660 Standard_Real u1,v1,u2,v2;
1661 mySurfInit->Bounds(u1,v1,u2,v2);
1662 GeomAdaptor_Surface Surf(mySurfInit);
1663 myTolU = Surf.UResolution(myTol3d);
1664 myTolV = Surf.VResolution(myTol3d);
1665 myProj.Initialize(Surf,u1,v1,u2,v2,
1668 //======================================================================
1669 // Projection of curves
1670 //======================================================================
1672 for (i = 1; i <= NTLinCont; i++)
1673 if (myLinCont->Value(i)->Curve2dOnSurf().IsNull())
1674 myLinCont->ChangeValue(i)->SetCurve2dOnSurf(ProjectCurve(myLinCont->Value(i)->Curve3d()));
1676 //======================================================================
1677 // Projection of points
1678 //======================================================================
1679 for (i = 1; i<=NTPntCont; i++)
1681 myPntCont->Value(i)->D0(P);
1682 if (!myPntCont->Value(i)->HasPnt2dOnSurf())
1683 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
1686 //======================================================================
1687 // Number of points by curve
1688 //======================================================================
1689 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
1692 //======================================================================
1693 // Management of incompatibilities between curves
1694 //======================================================================
1695 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
1696 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
1699 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1700 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1701 Intersect(PntInter, PntG1G1);
1704 //====================================================================
1705 // Discretization of curves
1706 //====================================================================
1707 Discretise(PntInter, PntG1G1);
1708 //====================================================================
1709 //Preparation of points of constraint for plate
1710 //====================================================================
1712 if (myPntCont->Length() != 0)
1714 //====================================================================
1715 // Construction of the surface
1716 //====================================================================
1717 Message_ProgressScope aPS(theProgress, "ComputeSurfInit", 1);
1718 myPlate.SolveTI(2, ComputeAnisotropie(), aPS.Next());
1719 if (theProgress.UserBreak())
1724 if (!myPlate.IsDone())
1727 std::cout << "WARNING : GeomPlate : calculation of Plate failed" << std::endl;
1732 myGeomPlateSurface = new GeomPlate_Surface( mySurfInit, myPlate );
1734 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
1738 mySurfInit = App.Surface();
1740 mySurfInitIsGive = Standard_True;
1741 myPlate.Init(); // Reset
1743 for (i=1;i<=NTLinCont;i++)
1745 Handle( Geom2d_Curve ) NullCurve;
1746 NullCurve.Nullify();
1747 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( NullCurve);
1754 sprintf(name,"surfinit_%d",++NbPlan);
1755 DrawTrSurf::Set(name, mySurfInit);
1760 //---------------------------------------------------------
1761 // Function : Intersect
1762 //---------------------------------------------------------
1763 // Find intersections between 2d curves
1764 // If the intersection is compatible (in cases G1-G1)
1765 // remove the point on one of two curves
1766 //---------------------------------------------------------
1767 void GeomPlate_BuildPlateSurface::
1768 Intersect(Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1769 Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1771 Standard_Integer NTLinCont = myLinCont->Length();
1772 Geom2dInt_GInter Intersection;
1773 Geom2dAdaptor_Curve Ci, Cj;
1774 IntRes2d_IntersectionPoint int2d;
1778 // if (!mySurfInitIsGive)
1779 for (Standard_Integer i=1;i<=NTLinCont;i++)
1781 //Standard_Real NbPnt_i=myLinCont->Value(i)->NbPoints();
1782 // Find the intersection with each curve including the curve itself
1783 Ci.Load(myLinCont->Value(i)->Curve2dOnSurf());
1784 for(Standard_Integer j=i; j<=NTLinCont; j++)
1786 Cj.Load(myLinCont->Value(j)->Curve2dOnSurf());
1788 Intersection.Perform(Ci, myTol2d*10, myTol2d*10);
1790 Intersection.Perform(Ci, Cj, myTol2d*10, myTol2d*10);
1792 if (!Intersection.IsEmpty())
1793 { // there is one intersection
1794 Standard_Integer nbpt = Intersection.NbPoints();
1795 // number of points of intersection
1796 for (Standard_Integer k = 1; k <= nbpt; k++)
1797 { int2d = Intersection.Point(k);
1798 myLinCont->Value(i)->D0(int2d.ParamOnFirst(),P1);
1799 myLinCont->Value(j)->D0(int2d.ParamOnSecond(),P2);
1803 std::cout << " Intersection "<< k << " entre " << i
1804 << " &" << j << std::endl;
1805 std::cout <<" Distance = "<< P1.Distance(P2) << std::endl;
1808 if (P1.Distance( P2 ) < myTol3d)
1809 { // 2D intersection corresponds to close 3D points.
1810 // Note the interval, in which the point needs to be removed
1811 // to avoid duplications, which cause
1812 // error in plate. The point on curve i is removed;
1813 // the point on curve j is preserved;
1814 // the length of interval is a length 2d
1815 // corresponding in 3d to myTol3d
1816 Standard_Real tolint = Ci.Resolution(myTol3d);
1817 Ci.D1(int2d.ParamOnFirst(),P2d, V2d);
1818 Standard_Real aux = V2d.Magnitude();
1822 if (aux > 100*tolint) tolint*=100;
1827 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1828 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1830 if ( (myLinCont->Value(i)->Order()==1)
1831 &&(myLinCont->Value(j)->Order()==1))
1832 { gp_Vec v11,v12,v13,v14,v15,v16,v21,v22,v23,v24,v25,v26;
1833 myLinCont->Value(i)->D2( int2d.ParamOnFirst(), P1, v11, v12, v13, v14, v15 );
1834 myLinCont->Value(j)->D2( int2d.ParamOnSecond(), P2, v21, v22, v23, v24, v25 );
1835 v16=v11^v12;v26=v21^v22;
1836 Standard_Real ant=v16.Angle(v26);
1839 if ((Abs(v16*v15-v16*v25)>(myTol3d/1000))
1840 ||(Abs(ant)>myTol3d/1000))
1841 // Non-compatible ==> remove zone in constraint G1
1842 // corresponding to 3D tolerance of 0.01
1843 { Standard_Real coin;
1844 Standard_Real Tol= 100 * myTol3d;
1846 gp_Pnt2d P1temp,P2temp;
1848 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1temp, V1);
1849 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2temp, V2);
1853 if (Abs(Abs(A1)-M_PI)<myTolAng) Tol = 100000 * myTol3d;
1855 if (Affich) std::cout <<"Angle between curves "<<i<<","<<j
1856 <<" "<<Abs(Abs(A1)-M_PI)<<std::endl;
1859 coin = Ci.Resolution(Tol);
1860 Standard_Real Par1=int2d.ParamOnFirst()-coin,
1861 Par2=int2d.ParamOnFirst()+coin;
1862 // Storage of the interval for curve i
1863 PntG1G1->ChangeValue(i).Append(Par1);
1864 PntG1G1->ChangeValue(i).Append(Par2);
1865 coin = Cj.Resolution(Tol);
1866 Par1=int2d.ParamOnSecond()-coin;
1867 Par2=int2d.ParamOnSecond()+coin;
1868 // Storage of the interval for curve j
1869 PntG1G1->ChangeValue(j).Append(Par1);
1870 PntG1G1->ChangeValue(j).Append(Par2);
1874 if ((myLinCont->Value(i)->Order()==0 && myLinCont->Value(j)->Order()==1) ||
1875 (myLinCont->Value(i)->Order()==1 && myLinCont->Value(j)->Order()==0))
1877 gp_Vec vec, vecU, vecV, N;
1878 if (myLinCont->Value(i)->Order() == 0)
1880 Handle( Adaptor3d_Curve ) theCurve = myLinCont->Value(i)->Curve3d();
1881 theCurve->D1( int2d.ParamOnFirst(), P1, vec );
1882 myLinCont->Value(j)->D1( int2d.ParamOnSecond(), P2, vecU, vecV );
1886 Handle( Adaptor3d_Curve ) theCurve = myLinCont->Value(j)->Curve3d();
1887 theCurve->D1( int2d.ParamOnSecond(), P2, vec );
1888 myLinCont->Value(i)->D1( int2d.ParamOnFirst(), P1, vecU, vecV );
1891 Standard_Real Angle = vec.Angle( N );
1892 Angle = Abs( M_PI/2-Angle );
1893 if (Angle > myTolAng/10.) //????????? //if (Abs( scal ) > myTol3d/100)
1895 // Non-compatible ==> one removes zone in constraint G0 and G1
1896 // corresponding to 3D tolerance of 0.01
1898 Standard_Real Tol= 100 * myTol3d;
1900 gp_Pnt2d P1temp,P2temp;
1902 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1temp, V1);
1903 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2temp, V2);
1904 A1 = V1.Angle( V2 );
1907 if (Abs(Abs(A1) - M_PI) < myTolAng) Tol = 100000 * myTol3d;
1909 if (Affich) std::cout <<"Angle entre Courbe "<<i<<","<<j
1910 <<" "<<Abs(Abs(A1)-M_PI)<<std::endl;
1912 if (myLinCont->Value(i)->Order() == 1)
1914 coin = Ci.Resolution(Tol);
1915 coin *= Angle / myTolAng * 10.;
1917 std::cout<<std::endl<<"coin = "<<coin<<std::endl;
1919 Standard_Real Par1 = int2d.ParamOnFirst() - coin;
1920 Standard_Real Par2 = int2d.ParamOnFirst() + coin;
1921 // Storage of the interval for curve i
1922 PntG1G1->ChangeValue(i).Append( Par1 );
1923 PntG1G1->ChangeValue(i).Append( Par2 );
1927 coin = Cj.Resolution(Tol);
1928 coin *= Angle / myTolAng * 10.;
1930 std::cout<<std::endl<<"coin = "<<coin<<std::endl;
1932 Standard_Real Par1 = int2d.ParamOnSecond() - coin;
1933 Standard_Real Par2 = int2d.ParamOnSecond() + coin;
1934 // Storage of the interval for curve j
1935 PntG1G1->ChangeValue(j).Append( Par1 );
1936 PntG1G1->ChangeValue(j).Append( Par2 );
1940 } //if (P1.Distance( P2 ) < myTol3d)
1942 // 2D intersection corresponds to extended 3D points.
1943 // Note the interval where it is necessary to remove
1944 // the points to avoid duplications causing
1945 // error in plate. The point on curve i is removed,
1946 // the point on curve j is preserved.
1947 // The length of interval is 2D length
1948 // corresponding to the distance of points in 3D to myTol3d
1949 Standard_Real tolint, Dist;
1950 Dist = P1.Distance(P2);
1951 tolint = Ci.Resolution(Dist);
1952 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1953 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1956 tolint = Cj.Resolution(Dist);
1957 PntInter->ChangeValue(j).
1958 Append( int2d.ParamOnSecond() - tolint);
1959 PntInter->ChangeValue(j).
1960 Append( int2d.ParamOnSecond() + tolint);
1964 std::cout << "Attention: Two points 3d have the same projection dist = " << Dist << std::endl;
1969 Handle(Draw_Marker3D) mark = new (Draw_Marker3D)(P1, Draw_X, Draw_vert);
1971 sprintf(name,"mark_%d",++NbMark);
1972 Draw::Set(name, mark);
1982 //---------------------------------------------------------
1983 // Function : Discretize
1984 //---------------------------------------------------------
1985 // Discretize curves according to parameters
1986 // the table of sequences Parcont contains all
1987 // parameter of points on curves
1988 // Field myPlateCont contains parameter of points on a plate;
1989 // it excludes duplicate points and imcompatible zones.
1990 // The first part corresponds to verification of compatibility
1991 // and to removal of duplicate points.
1992 //---------------------------------------------------------
1993 void GeomPlate_BuildPlateSurface::
1994 Discretise(const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1995 const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1997 Standard_Integer NTLinCont = myLinCont->Length();
1998 Standard_Boolean ACR;
1999 Handle(Geom2d_Curve) C2d;
2000 Geom2dAdaptor_Curve AC2d;
2001 // Handle(Adaptor_HCurve2d) HC2d;
2002 Handle(Law_Interpol) acrlaw = new (Law_Interpol) ();
2003 myPlateCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
2004 myParCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
2007 //===========================================================================
2008 // Construction of the table containing parameters of constraint points
2009 //===========================================================================
2010 Standard_Real Uinit, Ufinal, Length2d=0, Inter;
2011 Standard_Real CurLength;
2012 Standard_Integer NbPnt_i, NbPtInter, NbPtG1G1;
2013 Handle(GeomPlate_CurveConstraint) LinCont;
2015 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2016 LinCont = myLinCont->Value(i);
2017 Uinit=LinCont->FirstParameter();
2018 Ufinal=LinCont->LastParameter();
2019 // HC2d=LinCont->ProjectedCurve();
2020 // if(HC2d.IsNull())
2021 // ACR = (!HC2d.IsNull() || !C2d.IsNull());
2022 C2d= LinCont->Curve2dOnSurf();
2023 ACR = (!C2d.IsNull());
2025 // Construct a law close to curvilinear abscissa
2026 if(!C2d.IsNull()) AC2d.Load(C2d);
2027 // AC2d.Load(LinCont->Curve2dOnSurf());
2028 Standard_Integer ii, Nbint = 20;
2030 TColgp_Array1OfPnt2d tabP2d(1, Nbint+1);
2031 tabP2d(1).SetY(Uinit);
2033 tabP2d(Nbint+1).SetY(Ufinal);
2034 /* if (!HC2d.IsNull())
2036 Length2d = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, Ufinal);
2038 Length2d = GCPnts_AbscissaPoint::Length(AC2d, Uinit, Ufinal);
2040 tabP2d(Nbint+1).SetX(Length2d);
2041 for (ii = 2; ii<= Nbint; ii++) {
2042 U = Uinit + (Ufinal-Uinit)*((1-Cos((ii-1)*M_PI/(Nbint)))/2);
2044 /* if (!HC2d.IsNull()) {
2045 Standard_Real L = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, U);
2049 tabP2d(ii).SetX(GCPnts_AbscissaPoint::Length(AC2d, Uinit, U));
2051 acrlaw->Set(tabP2d);
2054 NbPnt_i = (Standard_Integer )( LinCont->NbPoints());
2055 NbPtInter= PntInter->Value(i).Length();
2056 NbPtG1G1= PntG1G1->Value(i).Length();
2060 std::cout << "Courbe : " << i << std::endl;
2061 std::cout << " NbPnt, NbPtInter, NbPtG1G1 :" << NbPnt_i << ", "
2062 << NbPtInter << ", " << NbPtG1G1 << std::endl;
2065 for (Standard_Integer j=1; j<=NbPnt_i; j++)
2067 // Distribution of points in cosine following ACR 2D
2068 // To avoid points of accumulation in 2D
2069 //Inter=Uinit+(Uif)*((-cos(M_PI*((j-1)/(NbPnt_i-1)))+1)/2);
2071 Inter=Ufinal;// to avoid bug on Sun
2073 CurLength = Length2d*(1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2;
2074 Inter = acrlaw->Value(CurLength);
2077 Inter=Uinit+(Ufinal-Uinit)*((1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2);
2079 myParCont->ChangeValue(i).Append(Inter);// add a point
2082 for(Standard_Integer l=1;l<=NbPtInter;l+=2)
2084 // check if the point Inter is in the interval
2085 // PntInter[i] PntInter[i+1]
2086 // in which case it is not necessary to store it (problem with duplicates)
2087 if ((Inter>PntInter->Value(i).Value(l))
2088 &&(Inter<PntInter->Value(i).Value(l+1)))
2091 // leave the loop without storing the point
2095 if (l+1>=NbPtInter) {
2096 // one has parsed the entire table : the point
2097 // does not belong to a common point interval
2100 // if there exists an incompatible interval
2101 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2103 if ((Inter>PntG1G1->Value(i).Value(k))
2104 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2106 k=NbPtG1G1+2; // to leave the loop
2107 // Add points of constraint G0
2111 AC2d.D0(Inter, P2d);
2112 LinCont->D0(Inter,P3d);
2113 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2114 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2115 -PP.Coord(2)+P3d.Coord(2),
2116 -PP.Coord(3)+P3d.Coord(3));
2117 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2120 else // the point does not belong to interval G1
2124 myPlateCont->ChangeValue(i).Append(Inter);
2132 myPlateCont->ChangeValue(i).Append(Inter);
2141 if (NbPtG1G1!=0) // there exist an incompatible interval
2143 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2145 if ((Inter>PntG1G1->Value(i).Value(k))
2146 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2148 k=NbPtG1G1+2; // to leave the loop
2149 // Add points of constraint G0
2153 AC2d.D0(Inter, P2d);
2154 LinCont->D0(Inter,P3d);
2155 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2156 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2157 -PP.Coord(2)+P3d.Coord(2),
2158 -PP.Coord(3)+P3d.Coord(3));
2159 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2163 else // the point does not belong to interval G1
2167 myPlateCont->ChangeValue(i).Append(Inter);
2175 if ( ( (!mySurfInitIsGive)
2176 &&(Geom2dAdaptor_Curve(LinCont->Curve2dOnSurf()).GetType()!=GeomAbs_Circle))
2177 || ( (j>1) &&(j<NbPnt_i))) // exclude extremeties
2178 myPlateCont->ChangeValue(i).Append(Inter);// add the point
2184 //---------------------------------------------------------
2185 // Function : CalculNbPtsInit
2186 //---------------------------------------------------------
2187 // Calculate the number of points by curve depending on the
2188 // length for the first iteration
2189 //---------------------------------------------------------
2190 void GeomPlate_BuildPlateSurface::CalculNbPtsInit ()
2192 Standard_Real LenT=0;
2193 Standard_Integer NTLinCont=myLinCont->Length();
2194 Standard_Integer NTPoint=(Standard_Integer )( myNbPtsOnCur*NTLinCont);
2195 Standard_Integer i ;
2197 for ( i=1;i<=NTLinCont;i++)
2198 LenT+=myLinCont->Value(i)->Length();
2199 for ( i=1;i<=NTLinCont;i++)
2200 { Standard_Integer Cont=myLinCont->Value(i)->Order();
2202 { case 0 : // Case G0 *1.2
2203 myLinCont->ChangeValue(i)->SetNbPoints(
2204 Standard_Integer(1.2*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2206 case 1 : // Case G1 *1
2207 myLinCont->ChangeValue(i)->SetNbPoints(
2208 Standard_Integer(NTPoint*(myLinCont->Value(i)->Length())/LenT));
2210 case 2 : // Case G2 *0.7
2211 myLinCont->ChangeValue(i)->SetNbPoints(
2212 Standard_Integer(0.7*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2215 if (myLinCont->Value(i)->NbPoints()<3)
2216 myLinCont->ChangeValue(i)->SetNbPoints(3);
2219 //---------------------------------------------------------
2220 // Function : LoadCurve
2221 //---------------------------------------------------------
2222 // Starting from table myParCont load all the points noted in plate
2223 //---------------------------------------------------------
2224 void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle,
2225 const Standard_Integer OrderMax )
2229 Standard_Integer NTLinCont=myLinCont->Length(), i, j;
2230 Standard_Integer Tang, Nt;
2233 for (i=1; i<=NTLinCont; i++){
2234 Handle(GeomPlate_CurveConstraint) CC = myLinCont->Value(i);
2235 if (CC ->Order()!=-1) {
2236 Tang = Min(CC->Order(), OrderMax);
2237 Nt = myPlateCont->Value(i).Length();
2239 for (j=1; j<=Nt; j++) {// Loading of points G0 on boundaries
2240 CC ->D0(myPlateCont->Value(i).Value(j),P3d);
2241 if (!CC->ProjectedCurve().IsNull())
2242 P2d = CC->ProjectedCurve()->Value(myPlateCont->Value(i).Value(j));
2245 if (!CC->Curve2dOnSurf().IsNull())
2246 P2d = CC->Curve2dOnSurf()->Value(myPlateCont->Value(i).Value(j));
2248 P2d = ProjectPoint(P3d);
2250 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2251 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2252 -PP.Coord(2)+P3d.Coord(2),
2253 -PP.Coord(3)+P3d.Coord(3));
2254 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2257 // Loading of points G1
2258 if (Tang==1) { // ==1
2260 CC->D1( myPlateCont->Value(i).Value(j), PP, V1, V2 );
2261 mySurfInit->D1( P2d.Coord(1), P2d.Coord(2), PP, V3, V4 );
2263 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2264 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2267 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2270 else if (NbBoucle == 1)
2272 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2273 myPlate.Load( FreeGCC );
2276 gp_Vec DU, DV, Normal, DerPlateU, DerPlateV;
2279 //Normal.Normalize();
2280 Standard_Real norm = Normal.Magnitude();
2281 if (norm > 1.e-12) Normal /= norm;
2282 DerPlateU = myPrevPlate.EvaluateDerivative( P2d.XY(), 1, 0 );
2283 DerPlateV = myPrevPlate.EvaluateDerivative( P2d.XY(), 0, 1 );
2285 DU.SetLinearForm(-(V3 + DerPlateU).Dot(Normal), Normal, DerPlateU);
2286 DV.SetLinearForm(-(V4 + DerPlateV).Dot(Normal), Normal, DerPlateV);
2287 Plate_PinpointConstraint PinU( P2d.XY(), DU.XYZ(), 1, 0 );
2288 Plate_PinpointConstraint PinV( P2d.XY(), DV.XYZ(), 0, 1 );
2289 myPlate.Load( PinU );
2290 myPlate.Load( PinV );
2293 // Loading of points G2
2295 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2296 CC->D2(myPlateCont->Value(i).Value(j),
2298 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2300 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2301 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2302 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2303 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2306 Plate_GtoCConstraint GCC(P2d.XY(),D1init,D1final,D2init,D2final);
2309 // else // Good but too expansive
2311 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(),
2312 // D1init, D1final, D2init, D2final );
2313 // myPlate.Load( FreeGCC );
2323 //---------------------------------------------------------
2324 // Function : LoadPoint
2325 //---------------------------------------------------------
2326 //void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer NbBoucle,
2327 void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer ,
2328 const Standard_Integer OrderMax)
2332 Standard_Integer NTPntCont=myPntCont->Length();
2333 Standard_Integer Tang, i;
2334 // gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2336 // Loading of points of point constraints
2337 for (i=1;i<=NTPntCont;i++) {
2338 myPntCont->Value(i)->D0(P3d);
2339 P2d = myPntCont->Value(i)->Pnt2dOnSurf();
2340 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2341 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2342 -PP.Coord(2)+P3d.Coord(2),
2343 -PP.Coord(3)+P3d.Coord(3));
2344 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2346 Tang = Min(myPntCont->Value(i)->Order(), OrderMax);
2347 if (Tang==1) {// ==1
2349 myPntCont->Value(i)->D1(PP,V1,V2);
2350 mySurfInit->D1(P2d.Coord(1),P2d.Coord(2),PP,V3,V4);
2351 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2352 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2355 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2356 myPlate.Load( GCC );
2360 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2361 myPlate.Load( FreeGCC );
2364 // Loading of points G2 GeomPlate_PlateG0Criterion
2366 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2367 myPntCont->Value(i)->D2(PP,V1,V2,V5,V6,V7);
2368 // gp_Vec Tv2 = V1^V2;
2369 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2370 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2371 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2372 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2373 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2376 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final, D2init, D2final );
2377 myPlate.Load( GCC );
2379 // else // Good but too expansive
2381 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final, D2init//, D2final );
2382 // myPlate.Load( FreeGCC );
2388 //---------------------------------------------------------
2389 // Function : VerifSurface
2390 //---------------------------------------------------------
2391 Standard_Boolean GeomPlate_BuildPlateSurface::
2392 VerifSurface(const Standard_Integer NbBoucle)
2394 //======================================================================
2396 //======================================================================
2397 Standard_Integer NTLinCont=myLinCont->Length();
2398 Standard_Boolean Result=Standard_True;
2400 // variable for error calculation
2401 myG0Error=0,myG1Error =0, myG2Error=0;
2403 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2404 Handle(GeomPlate_CurveConstraint) LinCont;
2405 LinCont = myLinCont->Value(i);
2406 if (LinCont->Order()!=-1) {
2407 Standard_Integer NbPts_i = myParCont->Value(i).Length();
2410 Handle(TColStd_HArray1OfReal) tdist =
2411 new TColStd_HArray1OfReal(1,NbPts_i-1);
2412 Handle(TColStd_HArray1OfReal) tang =
2413 new TColStd_HArray1OfReal(1,NbPts_i-1);
2414 Handle(TColStd_HArray1OfReal) tcourb =
2415 new TColStd_HArray1OfReal(1,NbPts_i-1);
2417 EcartContraintesMil (i,tdist,tang,tcourb);
2419 Standard_Real diffDistMax=0, diffAngMax=0;
2420 //Standard_Real SdiffDist=0, SdiffAng=0;
2421 Standard_Integer NdiffDist=0,NdiffAng=0;
2424 for (Standard_Integer j=1;j<NbPts_i;j++)
2425 { if (tdist->Value(j)>myG0Error)
2426 myG0Error=tdist->Value(j);
2427 if (tang->Value(j)>myG1Error)
2428 myG1Error=tang->Value(j);
2429 if (tcourb->Value(j)>myG2Error)
2430 myG2Error=tcourb->Value(j);
2432 if (myParCont->Value(i).Length()>3)
2433 U=(myParCont->Value(i).Value(j)+myParCont->Value(i).Value(j+1))/2;
2435 U=LinCont->FirstParameter()+
2436 ( LinCont->LastParameter()-LinCont->FirstParameter())*(j-1)/(NbPts_i-2);
2437 Standard_Real diffDist=tdist->Value(j)-LinCont->G0Criterion(U),diffAng;
2438 if (LinCont->Order()>0)
2439 diffAng=tang->Value(j)-LinCont->G1Criterion(U);
2441 // find the maximum variation of error and calculate the average
2443 diffDist = diffDist/LinCont->G0Criterion(U);
2444 if (diffDist>diffDistMax)
2445 diffDistMax = diffDist;
2446 //SdiffDist+=diffDist;
2449 if ((Affich) && (NbBoucle == myNbIter)) {
2453 Handle(Draw_Marker3D) mark =
2454 new (Draw_Marker3D)(P, Draw_X, Draw_orange);
2456 sprintf(name,"mark_%d",++NbMark);
2457 Draw::Set(name, mark);
2458 if (!LinCont->ProjectedCurve().IsNull())
2459 P2d = LinCont->ProjectedCurve()->Value(U);
2461 { if (!LinCont->Curve2dOnSurf().IsNull())
2462 P2d = LinCont->Curve2dOnSurf()->Value(U);
2464 P2d = ProjectPoint(P);
2466 sprintf(name,"mark2d_%d",++NbMark);
2467 Handle(Draw_Marker2D) mark2d =
2468 new (Draw_Marker2D)(P2d, Draw_X, Draw_orange);
2469 Draw::Set(name, mark2d);
2474 if ((diffAng>0)&&(LinCont->Order()==1)) {
2475 diffAng=diffAng/myLinCont->Value(i)->G1Criterion(U);
2476 if (diffAng>diffAngMax)
2477 diffAngMax = diffAng;
2478 //SdiffAng+=diffAng;
2481 if ((Affich) && (NbBoucle == myNbIter)) {
2484 Handle(Draw_Marker3D) mark =
2485 new Draw_Marker3D(P, Draw_X, Draw_or);
2487 sprintf(name,"mark_%d",++NbMark);
2488 Draw::Set(name, mark);
2494 if (NdiffDist>0) {// at least one point is not acceptable in G0
2496 if(LinCont->Order()== 0)
2497 Coef = 0.6*Log(diffDistMax+7.4);
2498 //7.4 corresponds to the calculation of min. coefficient = 1.2 is e^1.2/0.6
2500 Coef = Log(diffDistMax+3.3);
2501 //3.3 corresponds to calculation of min. coefficient = 1.2 donc e^1.2
2504 //experimentally after the coefficient becomes bad for L cases
2505 if ((NbBoucle>1)&&(diffDistMax>2))
2509 if (LinCont->NbPoints()>=Floor(LinCont->NbPoints()*Coef))
2510 Coef=2;// to provide increase of the number of points
2512 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints() * Coef));
2513 Result=Standard_False;
2516 if (NdiffAng>0) // at least 1 point is not acceptable in G1
2517 { Standard_Real Coef=1.5;
2518 if ((LinCont->NbPoints()+1)>=Floor(LinCont->NbPoints()*Coef))
2521 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints()*Coef )) ;
2522 Result=Standard_False;
2528 if (myFree && NbBoucle == 1)
2529 myPrevPlate = myPlate;
2537 //---------------------------------------------------------
2538 // Function : VerifPoint
2539 //---------------------------------------------------------
2540 void GeomPlate_BuildPlateSurface::
2541 VerifPoints (Standard_Real& Dist,
2543 Standard_Real& Curv) const
2544 { Standard_Integer NTPntCont=myPntCont->Length();
2547 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
2548 Ang=0;Dist=0,Curv=0;
2549 Handle(GeomPlate_PointConstraint) PntCont;
2550 for (Standard_Integer i=1;i<=NTPntCont;i++) {
2551 PntCont = myPntCont->Value(i);
2552 switch (PntCont->Order())
2554 P2d = PntCont->Pnt2dOnSurf();
2556 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
2557 Dist = Pf.Distance(Pi);
2560 PntCont->D1(Pi, v1i, v2i);
2561 P2d = PntCont->Pnt2dOnSurf();
2562 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
2563 Dist = Pf.Distance(Pi);
2564 v3i = v1i^v2i; v3f=v1f^v2f;
2570 Handle(Geom_Surface) Splate (myGeomPlateSurface);
2571 LocalAnalysis_SurfaceContinuity CG2;
2572 P2d = PntCont->Pnt2dOnSurf();
2573 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
2575 CG2.ComputeAnalysis(Prop, PntCont->LPropSurf(),GeomAbs_G2);
2578 Curv=CG2.G2CurvatureGap();
2584 Standard_Real GeomPlate_BuildPlateSurface::ComputeAnisotropie() const
2594 Standard_Boolean GeomPlate_BuildPlateSurface::IsOrderG1() const
2596 Standard_Boolean result = Standard_True;
2597 for (Standard_Integer i = 1; i <= myLinCont->Length(); i++)
2598 if (myLinCont->Value(i)->Order() < 1)
2600 result = Standard_False;