1 // Created on: 1997-05-05
2 // Created by: Jerome LEMONIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
21 // Modification de l'interface
22 // Amelioration de l'aglo de remplissage
23 // 29-09-97 ; jct; correction du calcul des points doublons (tol 2d et non 3d)
24 // 16-10-97 ; jct; on remet un Raise au lieu du cout sous debug (sinon plantage dans k1fab)
25 // 03-11-97 ; jct; plus de reference a BRepAdaptor et BRepTools
29 #include <GeomPlate_BuildPlateSurface.ixx>
31 #include <TColStd_HArray1OfReal.hxx>
32 #include <TColgp_HArray1OfPnt.hxx>
35 #include <gp_Pnt2d.hxx>
37 #include <gp_Vec2d.hxx>
39 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <GCPnts_AbscissaPoint.hxx>
42 #include <Law_Interpol.hxx>
44 #include <Plate_PinpointConstraint.hxx>
45 #include <Plate_Plate.hxx>
46 #include <Plate_GtoCConstraint.hxx>
47 #include <Plate_D1.hxx>
48 #include <Plate_D2.hxx>
49 #include <Plate_FreeGtoCConstraint.hxx>
51 #include <Precision.hxx>
53 #include <GeomPlate_BuildAveragePlane.hxx>
54 #include <GeomPlate_HArray1OfSequenceOfReal.hxx>
56 #include <LocalAnalysis_SurfaceContinuity.hxx>
58 // pour les intersection entre les courbes
59 #include <Geom2dInt_GInter.hxx>
60 #include <IntRes2d_IntersectionPoint.hxx>
61 #include <Geom2dAdaptor_Curve.hxx>
62 #include <GeomAdaptor_Surface.hxx>
65 #include <Extrema_ExtPS.hxx>
66 #include <Extrema_POnSurf.hxx>
67 #include <ProjLib_CompProjectedCurve.hxx>
68 #include <ProjLib_HCompProjectedCurve.hxx>
69 #include <Approx_CurveOnSurface.hxx>
70 #include <GeomAdaptor.hxx>
71 #include <GeomAdaptor_HSurface.hxx>
72 #include <GeomLProp_SLProps.hxx>
73 #include <Geom2d_BezierCurve.hxx>
74 #include <TColgp_Array1OfPnt2d.hxx>
78 #include <OSD_Chronometer.hxx>
80 static Standard_Integer Affich=0;
82 // 1 : Display des Geometries et controle intermediaire
83 // 2 : Display du nombre de contrainte par courbe + Intersection
84 // 3 : Dump des contraintes dans Plate
85 static Standard_Integer NbPlan = 0;
86 //static Standard_Integer NbCurv2d = 0;
87 static Standard_Integer NbMark = 0;
88 static Standard_Integer NbProj = 0;
92 #include <DrawTrSurf.hxx>
93 #include <Draw_Marker3D.hxx>
94 #include <Draw_Marker2D.hxx>
98 #include <TColStd_SequenceOfInteger.hxx>
99 #include <TColgp_SequenceOfVec.hxx>
100 #include <TColgp_HArray2OfPnt.hxx>
101 #include <Geom_BSplineSurface.hxx>
102 #include <GeomPlate_SequenceOfAij.hxx>
103 #include <GeomPlate_MakeApprox.hxx>
106 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
107 // =========================================================
108 // C O N S T R U C T E U R S
109 // =========================================================
110 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
112 //---------------------------------------------------------
113 // Constructeur compatible avec l'ancienne version
114 //---------------------------------------------------------
115 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
116 const Handle(TColStd_HArray1OfInteger)& NPoints,
117 const Handle(GeomPlate_HArray1OfHCurveOnSurface)& TabCurve,
118 const Handle(TColStd_HArray1OfInteger)& Tang,
119 const Standard_Integer Degree,
120 const Standard_Integer NbIter,
121 const Standard_Real Tol2d,
122 const Standard_Real Tol3d,
123 const Standard_Real TolAng,
124 const Standard_Real TolCurv,
125 const Standard_Boolean Anisotropie
127 myAnisotropie(Anisotropie),
136 { Standard_Integer NTCurve=TabCurve->Length();// Nombre de contraintes lineaires
137 myNbPtsOnCur = 0; // Debrayage du calcul du nombre de points
138 // en fonction de la longueur
139 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
140 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
142 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
145 Standard_ConstructionError::Raise("GeomPlate : the bounds Array is null");
146 if (Tang->Length()==0)
147 Standard_ConstructionError::Raise("GeomPlate : the constraints Array is null");
148 Standard_Integer nbp = 0;
150 for ( i=1;i<=NTCurve;i++)
151 { nbp+=NPoints->Value(i);
154 Standard_ConstructionError::Raise("GeomPlate : the resolution is impossible if the number of constraints points is 0");
156 Standard_ConstructionError::Raise("GeomPlate ; the degree resolution must be upper of 2");
157 // Remplissage des champs passage de l'ancien constructeur au nouveau
158 for(i=1;i<=NTCurve;i++)
159 { Handle(GeomPlate_CurveConstraint) Cont = new GeomPlate_CurveConstraint
160 ( TabCurve->Value(i),
163 myLinCont->Append(Cont);
165 mySurfInitIsGive=Standard_False;
167 myIsLinear = Standard_True;
168 myFree = Standard_False;
171 //------------------------------------------------------------------
172 // Constructeur avec surface d'init et degre de resolution de plate
173 //------------------------------------------------------------------
174 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
175 const Handle(Geom_Surface)& Surf,
176 const Standard_Integer Degree,
177 const Standard_Integer NbPtsOnCur,
178 const Standard_Integer NbIter,
179 const Standard_Real Tol2d,
180 const Standard_Real Tol3d,
181 const Standard_Real TolAng,
182 const Standard_Real TolCurv,
183 const Standard_Boolean Anisotropie ) :
185 myAnisotropie(Anisotropie),
187 myNbPtsOnCur(NbPtsOnCur),
196 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
198 Standard_ConstructionError::Raise("GeomPlate : the degree resolution must be upper of 2");
199 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
200 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
201 mySurfInitIsGive=Standard_True;
203 myIsLinear = Standard_True;
204 myFree = Standard_False;
208 //---------------------------------------------------------
209 // Constructeur avec degre de resolution de plate
210 //---------------------------------------------------------
211 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
212 const Standard_Integer Degree,
213 const Standard_Integer NbPtsOnCur,
214 const Standard_Integer NbIter,
215 const Standard_Real Tol2d,
216 const Standard_Real Tol3d,
217 const Standard_Real TolAng,
218 const Standard_Real TolCurv,
219 const Standard_Boolean Anisotropie ) :
220 myAnisotropie(Anisotropie),
222 myNbPtsOnCur(NbPtsOnCur),
231 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
233 Standard_ConstructionError::Raise("GeomPlate : the degree resolution must be upper of 2");
234 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
235 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
236 mySurfInitIsGive=Standard_False;
238 myIsLinear = Standard_True;
239 myFree = Standard_False;
242 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
243 // =========================================================
244 // M E T H O D E S P U B L I Q U E S
245 // =========================================================
246 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
250 //-------------------------------------------------------------------------
251 // Fonction : TrierTab, Fonction interne, ne fait partie de la classe
252 //-------------------------------------------------------------------------
253 // Reordonne le tableau des permutations
254 // Apres l'appel a CourbeJointive l'ordre des courbes est modifie
255 // Ex : ordre init des courbe ==> A B C D E F
256 // Dans TabInit on note ==> 1 2 3 4 5 6
257 // apres CourbeJointive ==> A E C B D F
258 // TabInit ==> 1 5 3 2 4 6
259 // apres TrierTab le Tableau contient ==> 1 4 3 5 2 6
260 // On peut ainsi acceder a la 2eme courbe en prenant TabInit[2]
261 // c'est a dire la 4eme du tableau des courbes classees
262 //-------------------------------------------------------------------------
263 void TrierTab(Handle(TColStd_HArray1OfInteger)& Tab)
264 { // Trie le tableau des permutations pour retrouver l'ordre initial
265 Standard_Integer Nb=Tab->Length();
266 TColStd_Array1OfInteger TabTri(1,Nb);
267 for (Standard_Integer i=1;i<=Nb;i++)
268 TabTri.SetValue(Tab->Value(i),i);
269 Tab->ChangeArray1()=TabTri;
272 //---------------------------------------------------------
273 // Fonction : ProjectCurve
274 //---------------------------------------------------------
275 Handle(Geom2d_Curve) GeomPlate_BuildPlateSurface::ProjectCurve(const Handle(Adaptor3d_HCurve)& Curv)
276 { // Projection d'une courbe sur un plan
277 Handle(Geom2d_Curve) Curve2d ;
278 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
281 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTol3d/10, myTol3d/10);
283 Standard_Real Udeb, Ufin, ProjUdeb, ProjUfin;
284 Udeb = Curv->FirstParameter();
285 Ufin = Curv->LastParameter();
286 Projector.Bounds( 1, ProjUdeb, ProjUfin );
288 if (Projector.NbCurves() != 1 ||
289 Abs( Udeb-ProjUdeb ) > Precision::PConfusion() ||
290 Abs( Ufin-ProjUfin ) > Precision::PConfusion())
292 if (Projector.IsSinglePnt(1, P2d))
294 //solution ponctuelles
295 TColgp_Array1OfPnt2d poles(1, 2);
297 Curve2d = new (Geom2d_BezierCurve) (poles);
301 Curve2d.Nullify(); // Pas de solution continue
303 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
308 GeomAbs_Shape Continuity = GeomAbs_C1;
309 Standard_Integer MaxDegree = 10, MaxSeg;
310 Standard_Real Udeb, Ufin;
311 Handle(ProjLib_HCompProjectedCurve) HProjector =
312 new ProjLib_HCompProjectedCurve();
313 HProjector->Set(Projector);
314 Projector.Bounds(1, Udeb, Ufin);
316 MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
317 Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d,
318 Continuity, MaxDegree, MaxSeg,
319 Standard_False, Standard_True);
321 Curve2d = appr.Curve2d();
325 char* name = new char[100];
326 sprintf(name,"proj_%d",++NbProj);
327 DrawTrSurf::Set(name, Curve2d);
332 //---------------------------------------------------------
333 // Fonction : ProjectedCurve
334 //---------------------------------------------------------
335 Handle(Adaptor2d_HCurve2d) GeomPlate_BuildPlateSurface::ProjectedCurve( Handle(Adaptor3d_HCurve)& Curv)
336 { // Projection d'une courbe sur la surface d'init
338 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
340 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTolU/10, myTolV/10);
341 Handle(ProjLib_HCompProjectedCurve) HProjector =
342 new ProjLib_HCompProjectedCurve();
344 if (Projector.NbCurves() != 1) {
346 HProjector.Nullify(); // Pas de solution continue
348 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
353 Standard_Real First1,Last1,First2,Last2;
354 First1=Curv->FirstParameter();
355 Last1 =Curv->LastParameter();
356 Projector.Bounds(1,First2,Last2);
358 if (Abs(First1-First2) <= Max(myTolU,myTolV) &&
359 Abs(Last1-Last2) <= Max(myTolU,myTolV))
362 HProjector->Set(Projector);
363 HProjector = Handle(ProjLib_HCompProjectedCurve)::
364 DownCast(HProjector->Trim(First2,Last2,Precision::PConfusion()));
368 HProjector.Nullify(); // Pas de solution continue
370 cout << "BuildPlateSurace :: Pas de projection complete" << endl;
377 //---------------------------------------------------------
378 // Fonction : ProjectPoint
379 //---------------------------------------------------------
380 // Projete une point sur la surface d'init
381 //---------------------------------------------------------
382 gp_Pnt2d GeomPlate_BuildPlateSurface::ProjectPoint(const gp_Pnt &p3d)
385 Standard_Integer nearest = 1;
386 if( myProj.NbExt() > 1)
388 Standard_Real dist2mini = myProj.SquareDistance(1);
389 for (Standard_Integer i=2; i<=myProj.NbExt();i++)
391 if (myProj.SquareDistance(i) < dist2mini)
393 dist2mini = myProj.SquareDistance(i);
398 P=myProj.Point(nearest);
406 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
407 // =========================================================
408 // M E T H O D E S P U B L I Q U E S
409 // =========================================================
410 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
411 //---------------------------------------------------------
413 //---------------------------------------------------------
414 // Initialise les contraintes lineaires et ponctuelles
415 //---------------------------------------------------------
416 void GeomPlate_BuildPlateSurface::Init()
417 { myLinCont->Clear();
419 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
420 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
423 //---------------------------------------------------------
424 // Fonction : LoadInitSurface
425 //---------------------------------------------------------
426 // Charge la surface initiale
427 //---------------------------------------------------------
428 void GeomPlate_BuildPlateSurface::LoadInitSurface(const Handle(Geom_Surface)& Surf)
430 mySurfInitIsGive=Standard_True;
433 //---------------------------------------------------------
435 //---------------------------------------------------------
436 //---------------------------------------------------------
437 // Ajout d'une contrainte lineaire
438 //---------------------------------------------------------
439 void GeomPlate_BuildPlateSurface::
440 Add(const Handle(GeomPlate_CurveConstraint)& Cont)
441 { myLinCont->Append(Cont);
444 void GeomPlate_BuildPlateSurface::SetNbBounds( const Standard_Integer NbBounds )
446 myNbBounds = NbBounds;
449 //---------------------------------------------------------
451 //---------------------------------------------------------
452 //---------------------------------------------------------
453 // Ajout d'une contrainte ponctuelle
454 //---------------------------------------------------------
455 void GeomPlate_BuildPlateSurface::
456 Add(const Handle(GeomPlate_PointConstraint)& Cont)
458 myPntCont->Append(Cont);
461 //---------------------------------------------------------
463 // Calcul la surface de remplissage avec les contraintes chargees
464 //---------------------------------------------------------
465 void GeomPlate_BuildPlateSurface::Perform()
469 OSD_Chronometer Chrono;
475 myNbBounds = myLinCont->Length();
478 //=====================================================================
479 //Declaration des variables.
480 //=====================================================================
481 Standard_Integer NTLinCont = myLinCont->Length(),
482 NTPntCont = myPntCont->Length(), NbBoucle=0;
483 // La variable NTPoint peut etre enlevee
484 Standard_Boolean Fini=Standard_True;
485 if ((NTLinCont+NTPntCont)==0)
486 Standard_RangeError::Raise("GeomPlate : The number of constraints is null.");
488 //======================================================================
490 //======================================================================
491 if (!mySurfInitIsGive)
496 { // Tableau des permutations pour conserver l'ordre initial voir TrierTab
497 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
498 for (Standard_Integer l=1;l<=NTLinCont;l++)
499 myInitOrder->SetValue(l,l);
500 if (!CourbeJointive(myTol3d))
501 {// Standard_Failure::Raise("Curves are not joined");
503 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
506 TrierTab(myInitOrder); // Reordonne le tableau des permutations
508 else if(NTLinCont > 0)//Patch
510 mySense = new TColStd_HArray1OfInteger( 1, NTLinCont, 0 );
511 myInitOrder = new TColStd_HArray1OfInteger( 1, NTLinCont, 1 );
515 Standard_Real u1,v1,u2,v2;
516 mySurfInit->Bounds(u1,v1,u2,v2);
517 GeomAdaptor_Surface Surf(mySurfInit);
518 myTolU = Surf.UResolution(myTol3d);
519 myTolV = Surf.VResolution(myTol3d);
520 myProj.Initialize(Surf,u1,v1,u2,v2,
523 //======================================================================
524 // Projection des courbes
525 //======================================================================
527 Standard_Boolean Ok = Standard_True;
528 for (i = 1; i <= NTLinCont; i++)
529 if(myLinCont->Value(i)->Curve2dOnSurf().IsNull())
531 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
532 if (Curve2d.IsNull())
537 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
541 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
546 mySurfInit = App.Surface();
548 mySurfInit->Bounds(u1,v1,u2,v2);
549 GeomAdaptor_Surface Surf(mySurfInit);
550 myTolU = Surf.UResolution(myTol3d);
551 myTolV = Surf.VResolution(myTol3d);
552 myProj.Initialize(Surf,u1,v1,u2,v2,
556 for (i = 1; i <= NTLinCont; i++)
558 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
559 if (Curve2d.IsNull())
564 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
568 mySurfInit = myPlanarSurfInit;
570 mySurfInit->Bounds(u1,v1,u2,v2);
571 GeomAdaptor_Surface Surf(mySurfInit);
572 myTolU = Surf.UResolution(myTol3d);
573 myTolV = Surf.VResolution(myTol3d);
574 myProj.Initialize(Surf,u1,v1,u2,v2,
577 for (i = 1; i <= NTLinCont; i++)
578 myLinCont->ChangeValue(i)->
579 SetCurve2dOnSurf(ProjectCurve( myLinCont->Value(i)->Curve3d() ) );
581 else { // Project the points
582 for ( i=1;i<=NTPntCont;i++) {
584 myPntCont->Value(i)->D0(P);
585 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
590 //======================================================================
591 // Projection des points
592 //======================================================================
593 for ( i=1;i<=NTPntCont;i++) {
594 if (! myPntCont->Value(i)->HasPnt2dOnSurf()) {
596 myPntCont->Value(i)->D0(P);
597 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
601 //======================================================================
602 // Nbre de point par courbe
603 //======================================================================
604 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
607 //======================================================================
608 // Gestion des incompatibilites entre courbes
609 //======================================================================
610 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
611 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
612 if (NTLinCont != 0) {
613 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
614 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
615 Intersect(PntInter, PntG1G1);
618 //======================================================================
619 // Boucle pour obtenir une meilleur surface
620 //======================================================================
622 myFree = !myIsLinear;
627 if (Affich && NbBoucle) {
628 cout<<"Resultats boucle"<< NbBoucle << endl;
629 cout<<"DistMax="<<myG0Error<<endl;
631 cout<<"AngleMax="<<myG1Error<<endl;
633 cout<<"CourbMax="<<myG2Error<<endl;
638 { //====================================================================
639 // Calcul le nombre de point total et le maximum de points par courbe
640 //====================================================================
641 Standard_Integer NPointMax=0;
642 for (Standard_Integer i=1;i<=NTLinCont;i++)
643 if ((myLinCont->Value(i)->NbPoints())>NPointMax)
644 NPointMax=(Standard_Integer )( myLinCont->Value(i)->NbPoints());
645 //====================================================================
646 // Discretisation des courbes
647 //====================================================================
648 Discretise(PntInter, PntG1G1);
649 //====================================================================
650 //Preparation des points de contrainte pour plate
651 //====================================================================
652 LoadCurve( NbBoucle );
653 if ( myPntCont->Length() != 0)
654 LoadPoint( NbBoucle );
655 //====================================================================
656 //Resolution de la surface
657 //====================================================================
658 myPlate.SolveTI(myDegree, ComputeAnisotropie());
659 if (!myPlate.IsDone())
660 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
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 cout<<"Warning objectif non atteint"<<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 //Resolution de la surface
684 //====================================================================
685 myPlate.SolveTI(myDegree, ComputeAnisotropie());
686 if (!myPlate.IsDone())
687 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
688 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
689 Standard_Real Umin,Umax,Vmin,Vmax;
690 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
691 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
692 Fini = Standard_True;
693 Standard_Real di,an,cu;
694 VerifPoints(di,an,cu);
696 } while (!Fini); // Fin boucle pour meilleur surface
699 { cout<<"======== Resultats globaux ==========="<<endl;
700 cout<<"DistMax="<<myG0Error<<endl;
702 cout<<"AngleMax="<<myG1Error<<endl;
704 cout<<"CourbMax="<<myG2Error<<endl;
709 cout<<"*** FIN DE GEOMPLATE ***"<<endl;
710 cout<<"Temps de calcul : "<<Tps<<endl;
711 cout<<"Nombre de boucle : "<<NbBoucle<<endl;
715 //---------------------------------------------------------
716 // fonction : EcartContraintesMIL
717 //---------------------------------------------------------
718 void GeomPlate_BuildPlateSurface::
719 EcartContraintesMil ( const Standard_Integer c,
720 Handle(TColStd_HArray1OfReal)& d,
721 Handle(TColStd_HArray1OfReal)& an,
722 Handle(TColStd_HArray1OfReal)& courb)
724 Standard_Integer NbPt=myParCont->Value(c).Length();
729 NbPt=myParCont->Value(c).Length();
730 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
732 gp_Pnt2d P2d;Standard_Integer i;
733 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(c);
734 switch (LinCont->Order())
736 for (i=1; i<NbPt; i++)
737 { U = ( myParCont->Value(c).Value(i) +
738 myParCont->Value(c).Value(i+1) )/2;
740 if (!LinCont->ProjectedCurve().IsNull())
741 P2d = LinCont->ProjectedCurve()->Value(U);
743 { if (!LinCont->Curve2dOnSurf().IsNull())
744 P2d = LinCont->Curve2dOnSurf()->Value(U);
746 P2d = ProjectPoint(Pi);
748 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
751 d->ChangeValue(i) = Pf.Distance(Pi);
755 for (i=1; i<NbPt; i++)
756 { U = ( myParCont->Value(c).Value(i) +
757 myParCont->Value(c).Value(i+1) )/2;
758 LinCont->D1(U, Pi, v1i, v2i);
759 if (!LinCont->ProjectedCurve().IsNull())
760 P2d = LinCont->ProjectedCurve()->Value(U);
762 { if (!LinCont->Curve2dOnSurf().IsNull())
763 P2d = LinCont->Curve2dOnSurf()->Value(U);
765 P2d = ProjectPoint(Pi);
767 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
768 d->ChangeValue(i) = Pf.Distance(Pi);
769 v3i = v1i^v2i; v3f=v1f^v2f;
770 Standard_Real angle=v3f.Angle(v3i);
772 an->ChangeValue(i) = M_PI -angle;
774 an->ChangeValue(i) = angle;
779 Handle(Geom_Surface) Splate;
780 Splate = Handle(Geom_Surface)::DownCast(myGeomPlateSurface);
781 LocalAnalysis_SurfaceContinuity CG2;
782 for (i=1; i<NbPt; i++)
783 { U = ( myParCont->Value(c).Value(i) +
784 myParCont->Value(c).Value(i+1) )/2;
786 if (!LinCont->ProjectedCurve().IsNull())
787 P2d = LinCont->ProjectedCurve()->Value(U);
789 { if (!LinCont->Curve2dOnSurf().IsNull())
790 P2d = LinCont->Curve2dOnSurf()->Value(U);
792 P2d = ProjectPoint(Pi);
794 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
796 CG2.ComputeAnalysis(Prop, myLinCont->Value(c)->LPropSurf(U),
798 d->ChangeValue(i)=CG2.C0Value();
799 an->ChangeValue(i)=CG2.G1Angle();
800 courb->ChangeValue(i)=CG2.G2CurvatureGap();
808 //---------------------------------------------------------
809 // fonction : Disc2dContour
810 //---------------------------------------------------------
811 void GeomPlate_BuildPlateSurface::
812 Disc2dContour ( const Standard_Integer /*nbp*/,
813 TColgp_SequenceOfXY& Seq2d)
817 cout<<"nbp doit etre egal a 4 pour Disc2dContour"<<endl;
822 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
823 Standard_Integer NTCurve = myLinCont->Length();
824 Standard_Integer NTPntCont = myPntCont->Length();
828 Standard_Real u1,v1,u2,v2;
831 mySurfInit->Bounds(u1,v1,u2,v2);
832 GeomAdaptor_Surface Surf(mySurfInit);
833 myProj.Initialize(Surf,u1,v1,u2,v2,
836 for( i=1; i<=NTPntCont; i++)
837 if (myPntCont->Value(i)->Order()!=-1)
838 { P2d = myPntCont->Value(i)->Pnt2dOnSurf();
839 UV.SetX(P2d.Coord(1));
840 UV.SetY(P2d.Coord(2));
843 for(i=1; i<=NTCurve; i++)
845 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(i);
846 if (LinCont->Order()!=-1)
847 { Standard_Integer NbPt=myParCont->Value(i).Length();
848 // premier point de contrainte (j=0)
849 if (!LinCont->ProjectedCurve().IsNull())
850 P2d = LinCont->ProjectedCurve()->Value(myParCont->Value(i).Value(1));
853 { if (!LinCont->Curve2dOnSurf().IsNull())
854 P2d = LinCont->Curve2dOnSurf()->Value(myParCont->Value(i).Value(1));
858 LinCont->D0(myParCont->Value(i).Value(1),PP);
859 P2d = ProjectPoint(PP);
863 UV.SetX(P2d.Coord(1));
864 UV.SetY(P2d.Coord(2));
866 for (Standard_Integer j=2; j<NbPt; j++)
867 { Standard_Real Uj=myParCont->Value(i).Value(j),
868 Ujp1=myParCont->Value(i).Value(j+1);
869 if (!LinCont->ProjectedCurve().IsNull())
870 P2d = LinCont->ProjectedCurve()->Value((Ujp1+3*Uj)/4);
873 { if (!LinCont->Curve2dOnSurf().IsNull())
874 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+3*Uj)/4);
878 LinCont->D0((Ujp1+3*Uj)/4,PP);
879 P2d = ProjectPoint(PP);
882 UV.SetX(P2d.Coord(1));
883 UV.SetY(P2d.Coord(2));
885 // point milieu precedent
886 if (!LinCont->ProjectedCurve().IsNull())
887 P2d = LinCont->ProjectedCurve()->Value((Ujp1+Uj)/2);
890 { if (!LinCont->Curve2dOnSurf().IsNull())
891 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+Uj)/2);
895 LinCont->D0((Ujp1+Uj)/2,PP);
896 P2d = ProjectPoint(PP);
900 UV.SetX(P2d.Coord(1));
901 UV.SetY(P2d.Coord(2));
903 // point 3/4 precedent
904 if (!LinCont->ProjectedCurve().IsNull())
905 P2d = LinCont->ProjectedCurve()->Value((3*Ujp1+Uj)/4);
908 { if (!LinCont->Curve2dOnSurf().IsNull())
909 P2d = LinCont->Curve2dOnSurf()->Value((3*Ujp1+Uj)/4);
913 LinCont->D0((3*Ujp1+Uj)/4,PP);
914 P2d = ProjectPoint(PP);
918 UV.SetX(P2d.Coord(1));
919 UV.SetY(P2d.Coord(2));
921 // point de contrainte courant
922 if (!LinCont->ProjectedCurve().IsNull())
923 P2d = LinCont->ProjectedCurve()->Value(Ujp1);
926 { if (!LinCont->Curve2dOnSurf().IsNull())
927 P2d = LinCont->Curve2dOnSurf()->Value(Ujp1);
931 LinCont->D0(Ujp1,PP);
932 P2d = ProjectPoint(PP);
936 UV.SetX(P2d.Coord(1));
937 UV.SetY(P2d.Coord(2));
944 //---------------------------------------------------------
945 // fonction : Disc3dContour
946 //---------------------------------------------------------
947 void GeomPlate_BuildPlateSurface::
948 Disc3dContour (const Standard_Integer /*nbp*/,
949 const Standard_Integer iordre,
950 TColgp_SequenceOfXYZ& Seq3d)
954 cout<<"nbp doit etre egal a 4 pour Disc3dContour"<<endl;
955 if (iordre!=0&&iordre!=1)
956 cout<<"iordre incorrect pour Disc3dContour"<<endl;
960 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
961 Standard_Real u1,v1,u2,v2;
962 mySurfInit->Bounds(u1,v1,u2,v2);
963 GeomAdaptor_Surface Surf(mySurfInit);
964 myProj.Initialize(Surf,u1,v1,u2,v2,
965 Surf.UResolution(myTol3d),
966 Surf.VResolution(myTol3d));
967 Standard_Integer NTCurve = myLinCont->Length();
968 Standard_Integer NTPntCont = myPntCont->Length();
975 for( i=1; i<=NTPntCont; i++)
976 if (myPntCont->Value(i)->Order()!=-1)
978 { myPntCont->Value(i)->D0(P3d);
985 myPntCont->Value(i)->D1(P3d,v1h,v2h);
994 for(i=1; i<=NTCurve; i++)
995 if (myLinCont->Value(i)->Order()!=-1)
997 { Standard_Integer NbPt=myParCont->Value(i).Length();;
998 // premier point de contrainte (j=0)
999 // Standard_Integer NbPt=myParCont->Length();
1001 myLinCont->Value(i)->D0(myParCont->Value(i).Value(1),P3d);
1008 myLinCont->Value(i)->D1(myParCont->Value(i).Value(1),P3d,v1h,v2h);
1016 for (Standard_Integer j=2; j<NbPt; j++)
1017 { Standard_Real Uj=myParCont->Value(i).Value(j),
1018 Ujp1=myParCont->Value(i).Value(j+1);
1020 // point 1/4 precedent
1021 myLinCont->Value(i)->D0((Ujp1+3*Uj)/4,P3d);
1026 // point milieu precedent
1027 myLinCont->Value(i)->D0((Ujp1+Uj)/2,P3d);
1032 // point 3/4 precedent
1033 myLinCont->Value(i)->D0((3*Ujp1+Uj)/4,P3d);
1038 // point de contrainte courant
1039 myLinCont->Value(i)->D0(Ujp1,P3d);
1046 // point 1/4 precedent
1047 myLinCont->Value(i)->D1((Ujp1+3*Uj)/4,P3d,v1h,v2h);
1053 // point milieu precedent
1054 myLinCont->Value(i)->D1((Ujp1+Uj)/2,P3d,v1h,v2h);
1060 // point 3/4 precedent
1061 myLinCont->Value(i)->D1((3*Ujp1+Uj)/4,P3d,v1h,v2h);
1067 // point de contrainte courant
1068 myLinCont->Value(i)->D1(Ujp1,P3d,v1h,v2h);
1081 //---------------------------------------------------------
1082 // fonction : IsDone
1083 //---------------------------------------------------------
1084 Standard_Boolean GeomPlate_BuildPlateSurface::IsDone() const
1085 { return myPlate.IsDone();
1090 //---------------------------------------------------------
1091 // fonction : Surface
1092 //---------------------------------------------------------
1093 Handle_GeomPlate_Surface GeomPlate_BuildPlateSurface::Surface() const
1094 { return myGeomPlateSurface ;
1097 //---------------------------------------------------------
1098 // fonction : SurfInit
1099 //---------------------------------------------------------
1100 Handle_Geom_Surface GeomPlate_BuildPlateSurface::SurfInit() const
1101 { return mySurfInit ;
1105 //---------------------------------------------------------
1107 //---------------------------------------------------------
1108 Handle_TColStd_HArray1OfInteger GeomPlate_BuildPlateSurface::Sense() const
1109 { Standard_Integer NTCurve = myLinCont->Length();
1110 Handle(TColStd_HArray1OfInteger) Sens = new TColStd_HArray1OfInteger(1,
1112 for (Standard_Integer i=1; i<=NTCurve; i++)
1113 Sens->SetValue(i,mySense->Value(myInitOrder->Value(i)));
1119 //---------------------------------------------------------
1120 // fonction : Curve2d
1121 //---------------------------------------------------------
1122 Handle_TColGeom2d_HArray1OfCurve GeomPlate_BuildPlateSurface::Curves2d() const
1123 { Standard_Integer NTCurve = myLinCont->Length();
1124 Handle(TColGeom2d_HArray1OfCurve) C2dfin =
1125 new TColGeom2d_HArray1OfCurve(1,NTCurve);
1127 for (Standard_Integer i=1; i<=NTCurve; i++)
1128 C2dfin->SetValue(i,myLinCont->Value(myInitOrder->Value(i))->Curve2dOnSurf());
1134 //---------------------------------------------------------
1136 //---------------------------------------------------------
1137 Handle_TColStd_HArray1OfInteger GeomPlate_BuildPlateSurface::Order() const
1138 { Handle_TColStd_HArray1OfInteger result=
1139 new TColStd_HArray1OfInteger(1,myLinCont->Length());
1140 for (Standard_Integer i=1;i<=myLinCont->Length();i++)
1141 result->SetValue(myInitOrder->Value(i),i);
1146 //---------------------------------------------------------
1147 // fonction : G0Error
1148 //---------------------------------------------------------
1149 Standard_Real GeomPlate_BuildPlateSurface::G0Error() const
1153 //---------------------------------------------------------
1154 // fonction : G1Error
1155 //---------------------------------------------------------
1156 Standard_Real GeomPlate_BuildPlateSurface::G1Error() const
1160 //---------------------------------------------------------
1161 // fonction : G2Error
1162 //---------------------------------------------------------
1163 Standard_Real GeomPlate_BuildPlateSurface::G2Error() const
1167 //=======================================================================
1168 //function : G0Error
1170 //=======================================================================
1172 Standard_Real GeomPlate_BuildPlateSurface::G0Error( const Standard_Integer Index )
1174 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1175 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1176 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1177 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1178 Standard_Real MaxDistance = 0.;
1179 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1180 if (tdistance->Value(i) > MaxDistance)
1181 MaxDistance = tdistance->Value(i);
1185 //=======================================================================
1186 //function : G1Error
1188 //=======================================================================
1190 Standard_Real GeomPlate_BuildPlateSurface::G1Error( const Standard_Integer Index )
1192 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1193 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1194 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1195 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1196 Standard_Real MaxAngle = 0.;
1197 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1198 if (tangle->Value(i) > MaxAngle)
1199 MaxAngle = tangle->Value(i);
1203 //=======================================================================
1204 //function : G2Error
1206 //=======================================================================
1208 Standard_Real GeomPlate_BuildPlateSurface::G2Error( const Standard_Integer Index )
1210 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1211 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1212 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1213 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1214 Standard_Real MaxCurvature = 0.;
1215 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1216 if (tcurvature->Value(i) > MaxCurvature)
1217 MaxCurvature = tcurvature->Value(i);
1218 return MaxCurvature;
1221 Handle(GeomPlate_CurveConstraint) GeomPlate_BuildPlateSurface::CurveConstraint( const Standard_Integer order) const
1223 return myLinCont->Value(order);
1225 Handle(GeomPlate_PointConstraint) GeomPlate_BuildPlateSurface::PointConstraint( const Standard_Integer order) const
1227 return myPntCont->Value(order);
1229 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1230 // =========================================================
1231 // M E T H O D E S P R I V E S
1232 // =========================================================
1233 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1235 //=======================================================================
1236 // function : CourbeJointive
1237 // purpose : Effectue un chainage des courbes pour pouvoir calculer
1238 // la surface d'init avec la methode du flux maxi.
1239 // Retourne vrai si il s'agit d'un contour ferme.
1240 //=======================================================================
1242 Standard_Boolean GeomPlate_BuildPlateSurface::
1243 CourbeJointive(const Standard_Real tolerance)
1244 { Standard_Integer nbf = myLinCont->Length();
1245 Standard_Real Ufinal1,Uinit1,Ufinal2,Uinit2;
1246 mySense = new TColStd_HArray1OfInteger(1,nbf,0);
1247 Standard_Boolean result=Standard_True;
1248 Standard_Integer j=1,i;
1251 while (j <= (myNbBounds-1))
1253 Standard_Integer a=0;
1256 { result = Standard_False;
1260 { if (i > myNbBounds)
1261 { result = Standard_False;
1266 Uinit1=myLinCont->Value(j)->FirstParameter();
1267 Ufinal1=myLinCont->Value(j)->LastParameter();
1268 Uinit2=myLinCont->Value(i)->FirstParameter();
1269 Ufinal2=myLinCont->Value(i)->LastParameter();
1270 if (mySense->Value(j)==1)
1272 myLinCont->Value(j)->D0(Ufinal1,P1);
1273 myLinCont->Value(i)->D0(Uinit2,P2);
1274 if (P1.Distance(P2)<tolerance)
1276 Handle(GeomPlate_CurveConstraint) tampon = myLinCont->Value(j+1);
1277 myLinCont->SetValue(j+1,myLinCont->Value(i));
1278 myLinCont->SetValue(i,tampon);
1279 Standard_Integer Tmp=myInitOrder->Value(j+1);
1280 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1281 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1282 myInitOrder->SetValue(i,Tmp);
1287 mySense->SetValue(j+1,0);
1291 { myLinCont->Value(i)->D0(Ufinal2,P2);
1293 if (P1.Distance(P2)<tolerance)
1295 Handle(GeomPlate_CurveConstraint) tampon =
1296 myLinCont->Value(j+1);
1297 myLinCont->SetValue(j+1,myLinCont->Value(i));
1298 myLinCont->SetValue(i,tampon);
1299 Standard_Integer Tmp=myInitOrder->Value(j+1);
1300 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1301 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1302 myInitOrder->SetValue(i,Tmp);
1305 mySense->SetValue(j+1,1);
1313 Uinit1=myLinCont->Value( myNbBounds )->FirstParameter();
1314 Ufinal1=myLinCont->Value( myNbBounds )->LastParameter();
1315 Uinit2=myLinCont->Value(1)->FirstParameter();
1316 Ufinal2=myLinCont->Value(1)->LastParameter();
1317 myLinCont->Value( myNbBounds )->D0(Ufinal1,P1);
1318 myLinCont->Value(1)->D0(Uinit2,P2);
1319 if ((mySense->Value( myNbBounds )==0)
1320 &&(P1.Distance(P2)<tolerance))
1322 return ((Standard_True)&&(result));
1324 myLinCont->Value( myNbBounds )->D0(Uinit1,P1);
1325 if ((mySense->Value( myNbBounds )==1)
1326 &&(P1.Distance(P2)<tolerance))
1328 return ((Standard_True)&&(result));
1330 else return Standard_False;
1334 //-------------------------------------------------------------------------
1335 // fonction : ComputeSurfInit
1336 //-------------------------------------------------------------------------
1337 // Calcul la surface d'init soit par la methode du flux maxi soit par
1338 // la methode du plan d'inertie si le contour n'est pas ferme ou si
1339 // il y a des contraintes ponctuelles
1340 //-------------------------------------------------------------------------
1342 void GeomPlate_BuildPlateSurface::ComputeSurfInit()
1344 Standard_Integer nopt=2, popt=2, Np=1;
1345 Standard_Boolean isHalfSpace = Standard_True;
1346 Standard_Real LinTol = 0.001, AngTol = 0.001; //AngTol = 0.0001; //LinTol = 0.0001
1348 // Option pour le calcul du plan initial
1349 Standard_Integer NTLinCont = myLinCont->Length(), NTPntCont = myPntCont->Length();
1350 // Tableau des permutation pour conserver l'ordre initial voir TrierTab
1351 if (NTLinCont != 0) {
1352 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
1353 for (Standard_Integer i = 1; i <= NTLinCont; i++)
1354 myInitOrder->SetValue( i, i );
1357 Standard_Boolean CourbeJoint = (NTLinCont != 0) && CourbeJointive (myTol3d);
1358 if (CourbeJoint && IsOrderG1())
1361 // Tableau contenant le nuage de point pour le calcul du plan
1362 Standard_Integer NbPoint = 20, Discr = NbPoint/4, pnum = 0;
1363 Handle( TColgp_HArray1OfPnt ) Pts = new TColgp_HArray1OfPnt( 1, (NbPoint+1)*NTLinCont+NTPntCont );
1364 TColgp_SequenceOfVec Vecs, NewVecs;
1365 GeomPlate_SequenceOfAij Aset;
1366 Standard_Real Uinit, Ufinal, Uif;
1368 Standard_Integer i ;
1369 for ( i = 1; i <= NTLinCont; i++)
1371 Standard_Integer Order = myLinCont->Value(i)->Order();
1375 Uinit = myLinCont->Value(i)->FirstParameter();
1376 Ufinal = myLinCont->Value(i)->LastParameter();
1377 Uif = Ufinal - Uinit;
1378 if (mySense->Value(i) == 1)
1384 gp_Vec Vec1, Vec2, Normal;
1385 Standard_Boolean ToReverse = Standard_False;
1386 if (i > 1 && Order >= GeomAbs_G1)
1389 myLinCont->Value(i)->D1( Uinit, P, Vec1, Vec2 );
1390 Normal = Vec1 ^ Vec2;
1391 if (LastVec.IsOpposite( Normal, AngTol ))
1392 ToReverse = Standard_True;
1395 for (Standard_Integer j = 0; j <= NbPoint; j++)
1396 { // Nombre de point par courbe = 20
1397 // Repartition lineaire
1398 Standard_Real Inter = j*Uif/(NbPoint);
1399 if (Order < GeomAbs_G1 || j % Discr != 0)
1400 myLinCont->Value(i)->D0( Uinit+Inter, Pts->ChangeValue(++pnum) );
1403 myLinCont->Value(i)->D1( Uinit+Inter, Pts->ChangeValue(++pnum), Vec1, Vec2 );
1404 Normal = Vec1 ^ Vec2;
1408 Standard_Boolean isNew = Standard_True;
1409 Standard_Integer k ;
1410 for ( k = 1; k <= Vecs.Length(); k++)
1411 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1413 isNew = Standard_False;
1417 for (k = 1; k <= NewVecs.Length(); k++)
1418 if (NewVecs(k).IsEqual( Normal, LinTol, AngTol ))
1420 isNew = Standard_False;
1424 NewVecs.Append( Normal );
1427 if (Order >= GeomAbs_G1)
1429 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1434 } //for (i = 1; i <= NTLinCont; i++)
1438 for (i = 1; i <= NTPntCont; i++)
1440 Standard_Integer Order = myPntCont->Value(i)->Order();
1443 gp_Vec Vec1, Vec2, Normal;
1444 if (Order < GeomAbs_G1)
1445 myPntCont->Value(i)->D0( Pts->ChangeValue(++pnum) );
1448 myPntCont->Value(i)->D1( Pts->ChangeValue(++pnum), Vec1, Vec2 );
1449 Normal = Vec1 ^ Vec2;
1451 Standard_Boolean isNew = Standard_True;
1452 for (Standard_Integer k = 1; k <= Vecs.Length(); k++)
1453 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1455 isNew = Standard_False;
1460 NewVecs.Append( Normal );
1461 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1464 NewVecs(1).Reverse();
1465 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1471 } //for (i = 1; i <= NTPntCont; i++)
1475 Standard_Boolean NullExist = Standard_True;
1478 NullExist = Standard_False;
1479 for (i = 1; i <= Vecs.Length(); i++)
1480 if (Vecs(i).SquareMagnitude() == 0.)
1482 NullExist = Standard_True;
1487 GeomPlate_BuildAveragePlane BAP( Vecs, Pts );
1488 Standard_Real u1,u2,v1,v2;
1489 BAP.MinMaxBox(u1,u2,v1,v2);
1490 // On agrandit le bazar pour les projections
1491 Standard_Real du = u2 - u1;
1492 Standard_Real dv = v2 - v1;
1493 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1494 mySurfInit = new Geom_RectangularTrimmedSurface( BAP.Plane(), u1,u2,v1,v2 );
1496 } //if (isHalfSpace)
1500 cout<<endl<<"Normals are not in half space"<<endl<<endl;
1502 myIsLinear = Standard_False;
1505 } //if (NTLinCont != 0 && (CourbeJoint = CourbeJointive( myTol3d )) && IsOrderG1())
1508 TrierTab( myInitOrder ); // Reordonne le tableau des permutations
1512 if ( NTPntCont != 0)
1513 nopt = 1; //Calcul par la methode du plan d'inertie
1514 else if (!CourbeJoint || NTLinCont != myNbBounds)
1515 {// Standard_Failure::Raise("Curves are not joined");
1517 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
1522 Standard_Real LenT=0;
1523 Standard_Integer Npt=0;
1524 Standard_Integer NTPoint=20*NTLinCont;
1525 Standard_Integer i ;
1526 for ( i=1;i<=NTLinCont;i++)
1527 LenT+=myLinCont->Value(i)->Length();
1528 for (i=1;i<=NTLinCont;i++)
1529 { Standard_Integer NbPoint= (Standard_Integer )( NTPoint*(myLinCont->Value(i)->Length())/LenT);
1534 // Tableau contenant le nuage de point pour le calcul du plan
1535 Handle(TColgp_HArray1OfPnt) Pts = new TColgp_HArray1OfPnt(1,20*NTLinCont+NTPntCont);
1536 Standard_Integer NbPoint=20;
1537 Standard_Real Uinit,Ufinal, Uif;
1538 for ( i=1;i<=NTLinCont;i++)
1539 { Uinit=myLinCont->Value(i)->FirstParameter();
1540 Ufinal=myLinCont->Value(i)->LastParameter();
1542 if (mySense->Value(i) == 1)
1546 for (Standard_Integer j=0; j<NbPoint; j++)
1547 { // Nombre de point par courbe = 20
1548 // Repartition lineaire
1549 Standard_Real Inter=j*Uif/(NbPoint);
1551 myLinCont->Value(i)->D0(Uinit+Inter,P);
1552 Pts->SetValue(Np++,P);
1555 for (i=1;i<=NTPntCont;i++)
1557 myPntCont->Value(i)->D0(P);
1558 Pts->SetValue(Np++,P);
1562 GeomPlate_BuildAveragePlane BAP( Pts, NbPoint*myNbBounds, myTol3d/1000, popt, nopt );
1563 if (!BAP.IsPlane()) Standard_Failure::Raise("the initial surface is not a plane.");
1564 Standard_Real u1,u2,v1,v2;
1565 BAP.MinMaxBox(u1,u2,v1,v2);
1566 // On agrandit le bazar pour les projections
1567 Standard_Real du = u2 - u1;
1568 Standard_Real dv = v2 - v1;
1569 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1570 mySurfInit = new Geom_RectangularTrimmedSurface(BAP.Plane(),u1,u2,v1,v2);
1573 //Comparing metrics of curves and projected curves
1574 if (NTLinCont != 0 && myIsLinear)
1576 Handle( Geom_Surface ) InitPlane =
1577 (Handle( Geom_RectangularTrimmedSurface )::DownCast(mySurfInit))->BasisSurface();
1579 Standard_Real Ratio, R1 = 2., R2 = 0.6; //R1 = 3, R2 = 0.5;//R1 = 1.4, R2 = 0.8; //R1 = 5., R2 = 0.2;
1580 Handle( GeomAdaptor_HSurface ) hsur =
1581 new GeomAdaptor_HSurface( InitPlane );
1582 Standard_Integer NbPoint = 20;
1584 // gp_Vec DerC, DerCproj, DU, DV;
1589 for (Standard_Integer i = 1; i <= NTLinCont && myIsLinear; i++)
1591 Standard_Real FirstPar = myLinCont->Value(i)->FirstParameter();
1592 Standard_Real LastPar = myLinCont->Value(i)->LastParameter();
1593 Standard_Real Uif = (LastPar - FirstPar)/(NbPoint);
1595 Handle( Adaptor3d_HCurve ) Curve = myLinCont->Value(i)->Curve3d();
1596 ProjLib_CompProjectedCurve Projector( hsur, Curve, myTol3d, myTol3d );
1597 Handle( ProjLib_HCompProjectedCurve ) ProjCurve =
1598 new ProjLib_HCompProjectedCurve();
1599 ProjCurve->Set( Projector );
1600 Adaptor3d_CurveOnSurface AProj(ProjCurve, hsur);
1603 gp_Vec DerC, DerCproj;
1604 for (Standard_Integer j = 1 ; j < NbPoint && myIsLinear; j++)
1606 Standard_Real Inter = FirstPar + j*Uif;
1607 Curve->D1(Inter, P, DerC);
1608 AProj.D1(Inter, P, DerCproj);
1610 Standard_Real A1 = DerC.Magnitude();
1611 Standard_Real A2 = DerCproj.Magnitude();
1618 if (Ratio > R1 || Ratio < R2)
1620 myIsLinear = Standard_False;
1627 cout <<"Metrics are too different :"<< Ratio<<endl;
1629 // myIsLinear = Standard_True; // !!
1630 } //comparing metrics of curves and projected curves
1635 myPlanarSurfInit = mySurfInit;
1638 char* name = new char[100];
1639 sprintf(name,"planinit_%d",NbPlan+1);
1640 DrawTrSurf::Set(name, mySurfInit);
1643 Standard_Real u1,v1,u2,v2;
1644 mySurfInit->Bounds(u1,v1,u2,v2);
1645 GeomAdaptor_Surface Surf(mySurfInit);
1646 myTolU = Surf.UResolution(myTol3d);
1647 myTolV = Surf.VResolution(myTol3d);
1648 myProj.Initialize(Surf,u1,v1,u2,v2,
1651 //======================================================================
1652 // Projection des courbes
1653 //======================================================================
1655 for (i = 1; i <= NTLinCont; i++)
1656 if (myLinCont->Value(i)->Curve2dOnSurf().IsNull())
1657 myLinCont->ChangeValue(i)->SetCurve2dOnSurf(ProjectCurve(myLinCont->Value(i)->Curve3d()));
1659 //======================================================================
1660 // Projection des points
1661 //======================================================================
1662 for (i = 1; i<=NTPntCont; i++)
1664 myPntCont->Value(i)->D0(P);
1665 if (!myPntCont->Value(i)->HasPnt2dOnSurf())
1666 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
1669 //======================================================================
1670 // Nbre de point par courbe
1671 //======================================================================
1672 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
1675 //======================================================================
1676 // Gestion des incompatibilites entre courbes
1677 //======================================================================
1678 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
1679 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
1682 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1683 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1684 Intersect(PntInter, PntG1G1);
1687 //====================================================================
1688 // Discretisation des courbes
1689 //====================================================================
1690 Discretise(PntInter, PntG1G1);
1691 //====================================================================
1692 //Preparation des points de contrainte pour plate
1693 //====================================================================
1695 if (myPntCont->Length() != 0)
1697 //====================================================================
1698 //Resolution de la surface
1699 //====================================================================
1700 myPlate.SolveTI(2, ComputeAnisotropie());
1701 if (!myPlate.IsDone())
1702 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
1704 myGeomPlateSurface = new GeomPlate_Surface( mySurfInit, myPlate );
1706 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
1710 mySurfInit = App.Surface();
1712 mySurfInitIsGive = Standard_True;
1713 myPlate.Init(); // Reset
1715 for (i=1;i<=NTLinCont;i++)
1717 Handle( Geom2d_Curve ) NullCurve;
1718 NullCurve.Nullify();
1719 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( NullCurve);
1725 char* name = new char[100];
1726 sprintf(name,"surfinit_%d",++NbPlan);
1727 DrawTrSurf::Set(name, mySurfInit);
1732 //---------------------------------------------------------
1733 // fonction : Intersect
1734 //---------------------------------------------------------
1735 // Recherche les intersections entre les courbe 2d
1736 // Si intersection et compatible( dans le cas G1-G1)
1737 // enleve le point sur une des deux courbes
1738 //---------------------------------------------------------
1739 void GeomPlate_BuildPlateSurface::
1740 Intersect(Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1741 Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1743 Standard_Integer NTLinCont = myLinCont->Length();
1744 Geom2dInt_GInter Intersection;
1745 Geom2dAdaptor_Curve Ci, Cj;
1746 IntRes2d_IntersectionPoint int2d;
1750 // if (!mySurfInitIsGive)
1751 for (Standard_Integer i=1;i<=NTLinCont;i++)
1753 //Standard_Real NbPnt_i=myLinCont->Value(i)->NbPoints();
1754 // Cherche l'intersection avec chaque courbe y compris elle meme.
1755 Ci.Load(myLinCont->Value(i)->Curve2dOnSurf());
1756 for(Standard_Integer j=i; j<=NTLinCont; j++)
1758 Cj.Load(myLinCont->Value(j)->Curve2dOnSurf());
1760 Intersection.Perform(Ci, myTol2d*10, myTol2d*10);
1762 Intersection.Perform(Ci, Cj, myTol2d*10, myTol2d*10);
1764 if (!Intersection.IsEmpty())
1765 { // il existe une intersection
1766 Standard_Integer nbpt = Intersection.NbPoints();
1767 // nombre de point d'intersection
1768 for (Standard_Integer k = 1; k <= nbpt; k++)
1769 { int2d = Intersection.Point(k);
1770 myLinCont->Value(i)->D0(int2d.ParamOnFirst(),P1);
1771 myLinCont->Value(j)->D0(int2d.ParamOnSecond(),P2);
1775 cout << " Intersection "<< k << " entre " << i
1776 << " &" << j << endl;
1777 cout <<" Distance = "<< P1.Distance(P2) << endl;
1780 if (P1.Distance( P2 ) < myTol3d)
1781 { // L'intersection 2d correspond a des points 3d proches
1782 // On note l'intervalle dans lequel il faudra enlever
1783 // un point pour eviter les doublons ce qui fait une
1784 // erreur dans plate. le point sur la courbe i est enleve
1785 // on conserve celui de la courbe j
1786 // la longueur de l'intervalle est une longueur 2d
1787 // correspondant en 3d a myTol3d
1788 Standard_Real tolint = Ci.Resolution(myTol3d);
1789 Ci.D1(int2d.ParamOnFirst(),P2d, V2d);
1790 Standard_Real aux = V2d.Magnitude();
1794 if (aux > 100*tolint) tolint*=100;
1799 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1800 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1802 if ( (myLinCont->Value(i)->Order()==1)
1803 &&(myLinCont->Value(j)->Order()==1))
1804 { gp_Vec v11,v12,v13,v14,v15,v16,v21,v22,v23,v24,v25,v26;
1805 myLinCont->Value(i)->D2( int2d.ParamOnFirst(), P1, v11, v12, v13, v14, v15 );
1806 myLinCont->Value(j)->D2( int2d.ParamOnSecond(), P2, v21, v22, v23, v24, v25 );
1807 v16=v11^v12;v26=v21^v22;
1808 Standard_Real ant=v16.Angle(v26);
1811 if ((Abs(v16*v15-v16*v25)>(myTol3d/1000))
1812 ||(Abs(ant)>myTol3d/1000))
1813 // Pas compatible ==> on enleve une zone en
1814 // contrainte G1 correspondant
1815 // a une tolerance 3D de 0.01
1816 { Standard_Real coin;
1817 Standard_Real Tol= 100 * myTol3d;
1821 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1, V1);
1822 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2, V2);
1826 if (Abs(Abs(A1)-M_PI)<myTolAng) Tol = 100000 * myTol3d;
1828 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1829 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1832 coin = Ci.Resolution(Tol);
1833 Standard_Real Par1=int2d.ParamOnFirst()-coin,
1834 Par2=int2d.ParamOnFirst()+coin;
1835 // Stockage de l'intervalle pour la courbe i
1836 PntG1G1->ChangeValue(i).Append(Par1);
1837 PntG1G1->ChangeValue(i).Append(Par2);
1838 coin = Cj.Resolution(Tol);
1839 Par1=int2d.ParamOnSecond()-coin;
1840 Par2=int2d.ParamOnSecond()+coin;
1841 // Stockage de l'intervalle pour la courbe j
1842 PntG1G1->ChangeValue(j).Append(Par1);
1843 PntG1G1->ChangeValue(j).Append(Par2);
1847 if ((myLinCont->Value(i)->Order()==0 && myLinCont->Value(j)->Order()==1) ||
1848 (myLinCont->Value(i)->Order()==1 && myLinCont->Value(j)->Order()==0))
1850 gp_Vec vec, vecU, vecV, N;
1851 if (myLinCont->Value(i)->Order() == 0)
1853 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(i)->Curve3d();
1854 theCurve->D1( int2d.ParamOnFirst(), P1, vec );
1855 myLinCont->Value(j)->D1( int2d.ParamOnSecond(), P2, vecU, vecV );
1859 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(j)->Curve3d();
1860 theCurve->D1( int2d.ParamOnSecond(), P2, vec );
1861 myLinCont->Value(i)->D1( int2d.ParamOnFirst(), P1, vecU, vecV );
1864 Standard_Real Angle = vec.Angle( N );
1865 Angle = Abs( M_PI/2-Angle );
1866 if (Angle > myTolAng/10.) //????????? //if (Abs( scal ) > myTol3d/100)
1867 { // Pas compatible ==> on enleve une zone en
1868 // contrainte G0 et G1 correspondant
1869 // a une tolerance 3D de 0.01
1871 Standard_Real Tol= 100 * myTol3d;
1875 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1, V1);
1876 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2, V2);
1877 A1 = V1.Angle( V2 );
1880 if (Abs(Abs(A1) - M_PI) < myTolAng) Tol = 100000 * myTol3d;
1882 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1883 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1885 if (myLinCont->Value(i)->Order() == 1)
1887 coin = Ci.Resolution(Tol);
1888 coin *= Angle / myTolAng * 10.;
1890 cout<<endl<<"coin = "<<coin<<endl;
1892 Standard_Real Par1 = int2d.ParamOnFirst() - coin;
1893 Standard_Real Par2 = int2d.ParamOnFirst() + coin;
1894 // Stockage de l'intervalle pour la courbe i
1895 PntG1G1->ChangeValue(i).Append( Par1 );
1896 PntG1G1->ChangeValue(i).Append( Par2 );
1900 coin = Cj.Resolution(Tol);
1901 coin *= Angle / myTolAng * 10.;
1903 cout<<endl<<"coin = "<<coin<<endl;
1905 Standard_Real Par1 = int2d.ParamOnSecond() - coin;
1906 Standard_Real Par2 = int2d.ParamOnSecond() + coin;
1907 // Stockage de l'intervalle pour la courbe j
1908 PntG1G1->ChangeValue(j).Append( Par1 );
1909 PntG1G1->ChangeValue(j).Append( Par2 );
1913 } //if (P1.Distance( P2 ) < myTol3d)
1915 //L'intersection 2d correspond a des points 3d eloigne
1916 // On note l'intervalle dans lequel il faudra enlever
1917 // des points pour eviter les doublons ce qui fait une
1918 // erreur dans plate. le point sur la courbe i est enleve
1919 // on conserve celui de la courbe j.
1920 // la longueur de l'intervalle est une longueur 2d
1921 // correspondant a la distance des points en 3d a myTol3d
1922 Standard_Real tolint, Dist;
1923 Dist = P1.Distance(P2);
1924 tolint = Ci.Resolution(Dist);
1925 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1926 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1929 tolint = Cj.Resolution(Dist);
1930 PntInter->ChangeValue(j).
1931 Append( int2d.ParamOnSecond() - tolint);
1932 PntInter->ChangeValue(j).
1933 Append( int2d.ParamOnSecond() + tolint);
1937 cout<<"Attention: Deux points 3d ont la meme projection dist="
1943 Handle(Draw_Marker3D) mark = new (Draw_Marker3D)(P1, Draw_X, Draw_vert);
1944 char* name = new char[100];
1945 sprintf(name,"mark_%d",++NbMark);
1946 Draw::Set(name, mark);
1956 //---------------------------------------------------------
1957 // fonction : Discretise
1958 //---------------------------------------------------------
1959 // Discretise les courbes selon le parametre de celle-ci
1960 // le tableau des sequences Parcont contiendera tous les
1961 // parametres des points sur les courbes
1962 // Le champ myPlateCont contiendera les parametre des points envoye a plate
1963 // il excluera les points en double et les zones imcompatibles.
1964 // La premiere partie correspond a la verfication de la compatibilite
1965 // et a la supprssion des points en double.
1966 //---------------------------------------------------------
1967 void GeomPlate_BuildPlateSurface::
1968 Discretise(const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1969 const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1971 Standard_Integer NTLinCont = myLinCont->Length();
1972 Standard_Boolean ACR;
1973 Handle(Geom2d_Curve) C2d;
1974 Geom2dAdaptor_Curve AC2d;
1975 // Handle(Adaptor_HCurve2d) HC2d;
1976 Handle(Law_Interpol) acrlaw = new (Law_Interpol) ();
1977 myPlateCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1978 myParCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1981 //===========================================================================
1982 // Construction du tableau contenant les parametres des points de contrainte
1983 //===========================================================================
1984 Standard_Real Uinit, Ufinal, Length2d=0, Inter;
1985 Standard_Real CurLength;
1986 Standard_Integer NbPnt_i, NbPtInter, NbPtG1G1;
1987 Handle(GeomPlate_CurveConstraint) LinCont;
1989 for (Standard_Integer i=1;i<=NTLinCont;i++) {
1990 LinCont = myLinCont->Value(i);
1991 Uinit=LinCont->FirstParameter();
1992 Ufinal=LinCont->LastParameter();
1993 // HC2d=LinCont->ProjectedCurve();
1994 // if(HC2d.IsNull())
1995 // ACR = (!HC2d.IsNull() || !C2d.IsNull());
1996 C2d= LinCont->Curve2dOnSurf();
1997 ACR = (!C2d.IsNull());
1999 // On Construit une loi proche de l'abscisse curviligne
2000 if(!C2d.IsNull()) AC2d.Load(C2d);
2001 // AC2d.Load(LinCont->Curve2dOnSurf());
2002 Standard_Integer ii, Nbint = 20;
2004 TColgp_Array1OfPnt2d tabP2d(1, Nbint+1);
2005 tabP2d(1).SetY(Uinit);
2007 tabP2d(Nbint+1).SetY(Ufinal);
2008 /* if (!HC2d.IsNull())
2010 Length2d = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, Ufinal);
2012 Length2d = GCPnts_AbscissaPoint::Length(AC2d, Uinit, Ufinal);
2014 tabP2d(Nbint+1).SetX(Length2d);
2015 for (ii = 2; ii<= Nbint; ii++) {
2016 U = Uinit + (Ufinal-Uinit)*((1-Cos((ii-1)*M_PI/(Nbint)))/2);
2018 /* if (!HC2d.IsNull()) {
2019 Standard_Real L = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, U);
2023 tabP2d(ii).SetX(GCPnts_AbscissaPoint::Length(AC2d, Uinit, U));
2025 acrlaw->Set(tabP2d);
2028 NbPnt_i = (Standard_Integer )( LinCont->NbPoints());
2029 NbPtInter= PntInter->Value(i).Length();
2030 NbPtG1G1= PntG1G1->Value(i).Length();
2034 cout << "Courbe : " << i << endl;
2035 cout << " NbPnt, NbPtInter, NbPtG1G1 :" << NbPnt_i << ", "
2036 << NbPtInter << ", " << NbPtG1G1 << endl;
2039 for (Standard_Integer j=1; j<=NbPnt_i; j++)
2041 // repartition des points en cosinus selon l'ACR 2d
2042 // Afin d'eviter les points d'acumulation dans le 2d
2043 //Inter=Uinit+(Uif)*((-cos(M_PI*((j-1)/(NbPnt_i-1)))+1)/2);
2045 Inter=Ufinal;//pour parer au bug sur sun
2047 CurLength = Length2d*(1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2;
2048 Inter = acrlaw->Value(CurLength);
2051 Inter=Uinit+(Ufinal-Uinit)*((1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2);
2053 myParCont->ChangeValue(i).Append(Inter);// on ajoute le point
2056 for(Standard_Integer l=1;l<=NbPtInter;l+=2)
2058 //on cherche si le point Inter est dans l'intervalle
2059 //PntInter[i] PntInter[i+1]
2060 //auquelle cas il ne faudrait pas le stocker (pb de doublons)
2061 if ((Inter>PntInter->Value(i).Value(l))
2062 &&(Inter<PntInter->Value(i).Value(l+1)))
2065 // pour sortir de la boucle sans stocker le point
2069 if (l+1>=NbPtInter) {
2070 // on a parcouru tout le tableau : Le point
2071 // n'appartient pas a un interval point commun
2074 // est qu'il existe un intervalle incompatible
2075 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2077 if ((Inter>PntG1G1->Value(i).Value(k))
2078 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2080 k=NbPtG1G1+2; // pour sortir de la boucle
2081 // Ajouter les points de contrainte G0
2085 AC2d.D0(Inter, P2d);
2086 LinCont->D0(Inter,P3d);
2087 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2088 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2089 -PP.Coord(2)+P3d.Coord(2),
2090 -PP.Coord(3)+P3d.Coord(3));
2091 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2094 else // le point n'appartient pas a un interval G1
2098 myPlateCont->ChangeValue(i).Append(Inter);
2099 // on ajoute le point
2106 myPlateCont->ChangeValue(i).Append(Inter);
2107 // on ajoute le point
2115 if (NbPtG1G1!=0) // est qu'il existe un intervalle incompatible
2117 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2119 if ((Inter>PntG1G1->Value(i).Value(k))
2120 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2122 k=NbPtG1G1+2; // pour sortir de la boucle
2123 // Ajouter les points de contrainte G0
2127 AC2d.D0(Inter, P2d);
2128 LinCont->D0(Inter,P3d);
2129 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2130 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2131 -PP.Coord(2)+P3d.Coord(2),
2132 -PP.Coord(3)+P3d.Coord(3));
2133 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2137 else // le point n'appartient pas a un intervalle G1
2141 myPlateCont->ChangeValue(i).Append(Inter);
2142 // on ajoute le point
2149 if ( ( (!mySurfInitIsGive)
2150 &&(Geom2dAdaptor_Curve(LinCont->Curve2dOnSurf()).GetType()!=GeomAbs_Circle))
2151 || ( (j>1) &&(j<NbPnt_i))) //on enleve les extremites
2152 myPlateCont->ChangeValue(i).Append(Inter);// on ajoute le point
2158 //---------------------------------------------------------
2159 // fonction : CalculNbPtsInit
2160 //---------------------------------------------------------
2161 // Calcul du nombre de points par courbe en fonction de la longueur
2162 // pour la premiere iteration
2163 //---------------------------------------------------------
2164 void GeomPlate_BuildPlateSurface::CalculNbPtsInit ()
2166 Standard_Real LenT=0;
2167 Standard_Integer NTLinCont=myLinCont->Length();
2168 Standard_Integer NTPoint=(Standard_Integer )( myNbPtsOnCur*NTLinCont);
2169 Standard_Integer i ;
2171 for ( i=1;i<=NTLinCont;i++)
2172 LenT+=myLinCont->Value(i)->Length();
2173 for ( i=1;i<=NTLinCont;i++)
2174 { Standard_Integer Cont=myLinCont->Value(i)->Order();
2176 { case 0 : // Cas G0 *1.2
2177 myLinCont->ChangeValue(i)->SetNbPoints(
2178 Standard_Integer(1.2*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2180 case 1 : // Cas G1 *1
2181 myLinCont->ChangeValue(i)->SetNbPoints(
2182 Standard_Integer(NTPoint*(myLinCont->Value(i)->Length())/LenT));
2184 case 2 : // Cas G2 *0.7
2185 myLinCont->ChangeValue(i)->SetNbPoints(
2186 Standard_Integer(0.7*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2189 if (myLinCont->Value(i)->NbPoints()<3)
2190 myLinCont->ChangeValue(i)->SetNbPoints(3);
2193 //---------------------------------------------------------
2194 // fonction : LoadCurve
2195 //---------------------------------------------------------
2196 // A partir du tableau myParCont on charge tous les points notes dans plate
2197 //---------------------------------------------------------
2198 void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle,
2199 const Standard_Integer OrderMax )
2203 Standard_Integer NTLinCont=myLinCont->Length(), i, j;
2204 Standard_Integer Tang, Nt;
2207 for (i=1; i<=NTLinCont; i++){
2208 Handle(GeomPlate_CurveConstraint) CC = myLinCont->Value(i);
2209 if (CC ->Order()!=-1) {
2210 Tang = Min(CC->Order(), OrderMax);
2211 Nt = myPlateCont->Value(i).Length();
2213 for (j=1; j<=Nt; j++) {// Chargement des points G0 sur les frontieres
2214 CC ->D0(myPlateCont->Value(i).Value(j),P3d);
2215 if (!CC->ProjectedCurve().IsNull())
2216 P2d = CC->ProjectedCurve()->Value(myPlateCont->Value(i).Value(j));
2219 if (!CC->Curve2dOnSurf().IsNull())
2220 P2d = CC->Curve2dOnSurf()->Value(myPlateCont->Value(i).Value(j));
2222 P2d = ProjectPoint(P3d);
2224 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2225 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2226 -PP.Coord(2)+P3d.Coord(2),
2227 -PP.Coord(3)+P3d.Coord(3));
2228 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2231 // Chargement des points G1
2232 if (Tang==1) { // ==1
2234 CC->D1( myPlateCont->Value(i).Value(j), PP, V1, V2 );
2235 mySurfInit->D1( P2d.Coord(1), P2d.Coord(2), PP, V3, V4 );
2237 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2238 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2241 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2244 else if (NbBoucle == 1)
2246 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2247 myPlate.Load( FreeGCC );
2250 gp_Vec DU, DV, Normal, DerPlateU, DerPlateV;
2253 //Normal.Normalize();
2254 Standard_Real norm = Normal.Magnitude();
2255 if (norm > 1.e-12) Normal /= norm;
2256 DerPlateU = myPrevPlate.EvaluateDerivative( P2d.XY(), 1, 0 );
2257 DerPlateV = myPrevPlate.EvaluateDerivative( P2d.XY(), 0, 1 );
2259 DU.SetLinearForm(-(V3 + DerPlateU).Dot(Normal), Normal, DerPlateU);
2260 DV.SetLinearForm(-(V4 + DerPlateV).Dot(Normal), Normal, DerPlateV);
2261 Plate_PinpointConstraint PinU( P2d.XY(), DU.XYZ(), 1, 0 );
2262 Plate_PinpointConstraint PinV( P2d.XY(), DV.XYZ(), 0, 1 );
2263 myPlate.Load( PinU );
2264 myPlate.Load( PinV );
2267 // Chargement des points G2
2269 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2270 CC->D2(myPlateCont->Value(i).Value(j),
2272 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2274 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2275 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2276 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2277 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2280 Plate_GtoCConstraint GCC(P2d.XY(),D1init,D1final,D2init,D2final);
2283 // else // Good but too expansive
2285 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(),
2286 // D1init, D1final, D2init, D2final );
2287 // myPlate.Load( FreeGCC );
2297 //---------------------------------------------------------
2298 //fonction : LoadPoint
2299 //---------------------------------------------------------
2300 //void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer NbBoucle,
2301 void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer ,
2302 const Standard_Integer OrderMax)
2306 Standard_Integer NTPntCont=myPntCont->Length();
2307 Standard_Integer Tang, i;
2308 // gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2311 // Chargement des points de contraintes ponctuel
2312 for (i=1;i<=NTPntCont;i++) {
2313 myPntCont->Value(i)->D0(P3d);
2314 P2d = myPntCont->Value(i)->Pnt2dOnSurf();
2315 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2316 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2317 -PP.Coord(2)+P3d.Coord(2),
2318 -PP.Coord(3)+P3d.Coord(3));
2319 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2321 Tang = Min(myPntCont->Value(i)->Order(), OrderMax);
2322 if (Tang==1) {// ==1
2323 myPntCont->Value(i)->D1(PP,V1,V2);
2324 mySurfInit->D1(P2d.Coord(1),P2d.Coord(2),PP,V3,V4);
2325 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2326 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2329 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2330 myPlate.Load( GCC );
2334 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2335 myPlate.Load( FreeGCC );
2338 // Chargement des points G2 GeomPlate_PlateG0Criterion
2340 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2341 myPntCont->Value(i)->D2(PP,V1,V2,V5,V6,V7);
2342 // gp_Vec Tv2 = V1^V2;
2343 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2344 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2345 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2346 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2347 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2350 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final, D2init, D2final );
2351 myPlate.Load( GCC );
2353 // else // Good but too expansive
2355 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final, D2init//, D2final );
2356 // myPlate.Load( FreeGCC );
2362 //---------------------------------------------------------
2363 //fonction : VerifSurface
2364 //---------------------------------------------------------
2365 Standard_Boolean GeomPlate_BuildPlateSurface::
2366 VerifSurface(const Standard_Integer NbBoucle)
2368 //======================================================================
2369 // Calcul des erreurs
2370 //======================================================================
2371 Standard_Integer NTLinCont=myLinCont->Length();
2372 Standard_Boolean Result=Standard_True;
2374 // variable pour les calculs d erreur
2375 myG0Error=0,myG1Error =0, myG2Error=0;
2377 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2378 Handle(GeomPlate_CurveConstraint) LinCont;
2379 LinCont = myLinCont->Value(i);
2380 if (LinCont->Order()!=-1) {
2381 Standard_Integer NbPts_i = myParCont->Value(i).Length();
2384 Handle(TColStd_HArray1OfReal) tdist =
2385 new TColStd_HArray1OfReal(1,NbPts_i-1);
2386 Handle(TColStd_HArray1OfReal) tang =
2387 new TColStd_HArray1OfReal(1,NbPts_i-1);
2388 Handle(TColStd_HArray1OfReal) tcourb =
2389 new TColStd_HArray1OfReal(1,NbPts_i-1);
2391 EcartContraintesMil (i,tdist,tang,tcourb);
2393 Standard_Real diffDistMax=0,SdiffDist=0;
2394 Standard_Real diffAngMax=0,SdiffAng=0;
2395 Standard_Integer NdiffDist=0,NdiffAng=0;
2398 for (Standard_Integer j=1;j<NbPts_i;j++)
2399 { if (tdist->Value(j)>myG0Error)
2400 myG0Error=tdist->Value(j);
2401 if (tang->Value(j)>myG1Error)
2402 myG1Error=tang->Value(j);
2403 if (tcourb->Value(j)>myG2Error)
2404 myG2Error=tcourb->Value(j);
2406 if (myParCont->Value(i).Length()>3)
2407 U=(myParCont->Value(i).Value(j)+myParCont->Value(i).Value(j+1))/2;
2409 U=LinCont->FirstParameter()+
2410 ( LinCont->LastParameter()-LinCont->FirstParameter())*(j-1)/(NbPts_i-2);
2411 Standard_Real diffDist=tdist->Value(j)-LinCont->G0Criterion(U),diffAng;
2412 if (LinCont->Order()>0)
2413 diffAng=tang->Value(j)-LinCont->G1Criterion(U);
2415 // recherche de la variation de l'erreur maxi et calcul de la moyenne
2417 diffDist = diffDist/LinCont->G0Criterion(U);
2418 if (diffDist>diffDistMax)
2419 diffDistMax = diffDist;
2420 SdiffDist+=diffDist;
2423 if ((Affich) && (NbBoucle == myNbIter)) {
2427 Handle(Draw_Marker3D) mark =
2428 new (Draw_Marker3D)(P, Draw_X, Draw_orange);
2429 char* name = new char[100];
2431 sprintf(name,"mark_%d",++NbMark);
2432 Draw::Set(name, mark);
2433 if (!LinCont->ProjectedCurve().IsNull())
2434 P2d = LinCont->ProjectedCurve()->Value(U);
2436 { if (!LinCont->Curve2dOnSurf().IsNull())
2437 P2d = LinCont->Curve2dOnSurf()->Value(U);
2439 P2d = ProjectPoint(P);
2441 sprintf(name,"mark2d_%d",++NbMark);
2442 Handle(Draw_Marker2D) mark2d =
2443 new (Draw_Marker2D)(P2d, Draw_X, Draw_orange);
2444 Draw::Set(name, mark2d);
2449 if ((diffAng>0)&&(LinCont->Order()==1)) {
2450 diffAng=diffAng/myLinCont->Value(i)->G1Criterion(U);
2451 if (diffAng>diffAngMax)
2452 diffAngMax = diffAng;
2456 if ((Affich) && (NbBoucle == myNbIter)) {
2459 Handle(Draw_Marker3D) mark =
2460 new Draw_Marker3D(P, Draw_X, Draw_or);
2461 char* name = new char[100];
2462 sprintf(name,"mark_%d",++NbMark);
2463 Draw::Set(name, mark);
2469 if (NdiffDist>0) {// au moins un point n'est pas acceptable en G0
2471 if(LinCont->Order()== 0)
2472 Coef = 0.6*Log(diffDistMax+7.4);
2473 //7.4 correspond au calcul du coef mini = 1.2 donc e^1.2/0.6
2475 Coef = Log(diffDistMax+3.3);
2476 //3.3 correspond au calcul du coef mini = 1.2 donc e^1.2
2479 //experimentalement apres le coef devient mauvais pour les cas L
2480 if ((NbBoucle>1)&&(diffDistMax>2))
2484 if (LinCont->NbPoints()>=Floor(LinCont->NbPoints()*Coef))
2485 Coef=2;// pour assurer une augmentation du nombre de points
2487 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints() * Coef));
2488 Result=Standard_False;
2491 if (NdiffAng>0) // au moins 1 points ne sont pas accepable en G1
2492 { Standard_Real Coef=1.5;
2493 if ((LinCont->NbPoints()+1)>=Floor(LinCont->NbPoints()*Coef))
2496 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints()*Coef )) ;
2497 Result=Standard_False;
2503 if (myFree && NbBoucle == 1)
2504 myPrevPlate = myPlate;
2512 //---------------------------------------------------------
2513 //fonction : VerifPoint
2514 //---------------------------------------------------------
2515 void GeomPlate_BuildPlateSurface::
2516 VerifPoints (Standard_Real& Dist,
2518 Standard_Real& Curv) const
2519 { Standard_Integer NTPntCont=myPntCont->Length();
2522 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
2523 Ang=0;Dist=0,Curv=0;
2524 Handle(GeomPlate_PointConstraint) PntCont;
2525 for (Standard_Integer i=1;i<=NTPntCont;i++) {
2526 PntCont = myPntCont->Value(i);
2527 switch (PntCont->Order())
2529 P2d = PntCont->Pnt2dOnSurf();
2531 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
2532 Dist = Pf.Distance(Pi);
2535 PntCont->D1(Pi, v1i, v2i);
2536 P2d = PntCont->Pnt2dOnSurf();
2537 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
2538 Dist = Pf.Distance(Pi);
2539 v3i = v1i^v2i; v3f=v1f^v2f;
2545 Handle(Geom_Surface) Splate;
2546 Splate = Handle(Geom_Surface)::DownCast(myGeomPlateSurface);
2547 LocalAnalysis_SurfaceContinuity CG2;
2548 P2d = PntCont->Pnt2dOnSurf();
2549 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
2551 CG2.ComputeAnalysis(Prop, PntCont->LPropSurf(),GeomAbs_G2);
2554 Curv=CG2.G2CurvatureGap();
2560 Standard_Real GeomPlate_BuildPlateSurface::ComputeAnisotropie() const
2570 Standard_Boolean GeomPlate_BuildPlateSurface::IsOrderG1() const
2572 Standard_Boolean result = Standard_True;
2573 for (Standard_Integer i = 1; i <= myLinCont->Length(); i++)
2574 if (myLinCont->Value(i)->Order() < 1)
2576 result = Standard_False;