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 // Modification de l'interface
18 // Amelioration de l'aglo de remplissage
19 // 29-09-97 ; jct; correction du calcul des points doublons (tol 2d et non 3d)
20 // 16-10-97 ; jct; on remet un Raise au lieu du cout sous debug (sinon plantage dans k1fab)
21 // 03-11-97 ; jct; plus de reference a BRepAdaptor et BRepTools
25 #include <GeomPlate_BuildPlateSurface.ixx>
27 #include <TColStd_HArray1OfReal.hxx>
28 #include <TColgp_HArray1OfPnt.hxx>
31 #include <gp_Pnt2d.hxx>
33 #include <gp_Vec2d.hxx>
35 #include <Geom_RectangularTrimmedSurface.hxx>
37 #include <GCPnts_AbscissaPoint.hxx>
38 #include <Law_Interpol.hxx>
40 #include <Plate_PinpointConstraint.hxx>
41 #include <Plate_Plate.hxx>
42 #include <Plate_GtoCConstraint.hxx>
43 #include <Plate_D1.hxx>
44 #include <Plate_D2.hxx>
45 #include <Plate_FreeGtoCConstraint.hxx>
47 #include <Precision.hxx>
49 #include <GeomPlate_BuildAveragePlane.hxx>
50 #include <GeomPlate_HArray1OfSequenceOfReal.hxx>
52 #include <LocalAnalysis_SurfaceContinuity.hxx>
54 // pour les intersection entre les courbes
55 #include <Geom2dInt_GInter.hxx>
56 #include <IntRes2d_IntersectionPoint.hxx>
57 #include <Geom2dAdaptor_Curve.hxx>
58 #include <GeomAdaptor_Surface.hxx>
61 #include <Extrema_ExtPS.hxx>
62 #include <Extrema_POnSurf.hxx>
63 #include <ProjLib_CompProjectedCurve.hxx>
64 #include <ProjLib_HCompProjectedCurve.hxx>
65 #include <Approx_CurveOnSurface.hxx>
66 #include <GeomAdaptor.hxx>
67 #include <GeomAdaptor_HSurface.hxx>
68 #include <GeomLProp_SLProps.hxx>
69 #include <Geom2d_BezierCurve.hxx>
70 #include <TColgp_Array1OfPnt2d.hxx>
72 #include <TColStd_SequenceOfInteger.hxx>
73 #include <TColgp_SequenceOfVec.hxx>
74 #include <TColgp_HArray2OfPnt.hxx>
75 #include <Geom_BSplineSurface.hxx>
76 #include <GeomPlate_SequenceOfAij.hxx>
77 #include <GeomPlate_MakeApprox.hxx>
80 #include <DrawTrSurf.hxx>
81 #include <Draw_Marker3D.hxx>
82 #include <Draw_Marker2D.hxx>
85 // 1 : Display des Geometries et controle intermediaire
86 // 2 : Display du nombre de contrainte par courbe + Intersection
87 // 3 : Dump des contraintes dans Plate
88 static Standard_Integer NbPlan = 0;
89 //static Standard_Integer NbCurv2d = 0;
90 static Standard_Integer NbMark = 0;
91 static Standard_Integer NbProj = 0;
96 #include <OSD_Chronometer.hxx>
97 static Standard_Integer Affich=0;
100 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
101 // =========================================================
102 // C O N S T R U C T E U R S
103 // =========================================================
104 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
106 //---------------------------------------------------------
107 // Constructeur compatible avec l'ancienne version
108 //---------------------------------------------------------
109 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
110 const Handle(TColStd_HArray1OfInteger)& NPoints,
111 const Handle(GeomPlate_HArray1OfHCurveOnSurface)& TabCurve,
112 const Handle(TColStd_HArray1OfInteger)& Tang,
113 const Standard_Integer Degree,
114 const Standard_Integer NbIter,
115 const Standard_Real Tol2d,
116 const Standard_Real Tol3d,
117 const Standard_Real TolAng,
118 const Standard_Real ,
119 const Standard_Boolean Anisotropie
121 myAnisotropie(Anisotropie),
129 { Standard_Integer NTCurve=TabCurve->Length();// Nombre de contraintes lineaires
130 myNbPtsOnCur = 0; // Debrayage du calcul du nombre de points
131 // en fonction de la longueur
132 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
133 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
135 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
138 Standard_ConstructionError::Raise("GeomPlate : the bounds Array is null");
139 if (Tang->Length()==0)
140 Standard_ConstructionError::Raise("GeomPlate : the constraints Array is null");
141 Standard_Integer nbp = 0;
143 for ( i=1;i<=NTCurve;i++)
144 { nbp+=NPoints->Value(i);
147 Standard_ConstructionError::Raise("GeomPlate : the resolution is impossible if the number of constraints points is 0");
149 Standard_ConstructionError::Raise("GeomPlate ; the degree resolution must be upper of 2");
150 // Remplissage des champs passage de l'ancien constructeur au nouveau
151 for(i=1;i<=NTCurve;i++)
152 { Handle(GeomPlate_CurveConstraint) Cont = new GeomPlate_CurveConstraint
153 ( TabCurve->Value(i),
156 myLinCont->Append(Cont);
158 mySurfInitIsGive=Standard_False;
160 myIsLinear = Standard_True;
161 myFree = Standard_False;
164 //------------------------------------------------------------------
165 // Constructeur avec surface d'init et degre de resolution de plate
166 //------------------------------------------------------------------
167 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
168 const Handle(Geom_Surface)& Surf,
169 const Standard_Integer Degree,
170 const Standard_Integer NbPtsOnCur,
171 const Standard_Integer NbIter,
172 const Standard_Real Tol2d,
173 const Standard_Real Tol3d,
174 const Standard_Real TolAng,
175 const Standard_Real /*TolCurv*/,
176 const Standard_Boolean Anisotropie ) :
178 myAnisotropie(Anisotropie),
180 myNbPtsOnCur(NbPtsOnCur),
188 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
190 Standard_ConstructionError::Raise("GeomPlate : the degree resolution must be upper of 2");
191 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
192 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
193 mySurfInitIsGive=Standard_True;
195 myIsLinear = Standard_True;
196 myFree = Standard_False;
200 //---------------------------------------------------------
201 // Constructeur avec degre de resolution de plate
202 //---------------------------------------------------------
203 GeomPlate_BuildPlateSurface::GeomPlate_BuildPlateSurface (
204 const Standard_Integer Degree,
205 const Standard_Integer NbPtsOnCur,
206 const Standard_Integer NbIter,
207 const Standard_Real Tol2d,
208 const Standard_Real Tol3d,
209 const Standard_Real TolAng,
210 const Standard_Real /*TolCurv*/,
211 const Standard_Boolean Anisotropie ) :
212 myAnisotropie(Anisotropie),
214 myNbPtsOnCur(NbPtsOnCur),
222 Standard_ConstructionError::Raise("GeomPlate : Number of iteration must be >= 1");
224 Standard_ConstructionError::Raise("GeomPlate : the degree resolution must be upper of 2");
225 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
226 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
227 mySurfInitIsGive=Standard_False;
229 myIsLinear = Standard_True;
230 myFree = Standard_False;
233 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
234 // =========================================================
235 // M E T H O D E S P U B L I Q U E S
236 // =========================================================
237 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
241 //-------------------------------------------------------------------------
242 // Fonction : TrierTab, Fonction interne, ne fait partie de la classe
243 //-------------------------------------------------------------------------
244 // Reordonne le tableau des permutations
245 // Apres l'appel a CourbeJointive l'ordre des courbes est modifie
246 // Ex : ordre init des courbe ==> A B C D E F
247 // Dans TabInit on note ==> 1 2 3 4 5 6
248 // apres CourbeJointive ==> A E C B D F
249 // TabInit ==> 1 5 3 2 4 6
250 // apres TrierTab le Tableau contient ==> 1 4 3 5 2 6
251 // On peut ainsi acceder a la 2eme courbe en prenant TabInit[2]
252 // c'est a dire la 4eme du tableau des courbes classees
253 //-------------------------------------------------------------------------
254 void TrierTab(Handle(TColStd_HArray1OfInteger)& Tab)
255 { // Trie le tableau des permutations pour retrouver l'ordre initial
256 Standard_Integer Nb=Tab->Length();
257 TColStd_Array1OfInteger TabTri(1,Nb);
258 for (Standard_Integer i=1;i<=Nb;i++)
259 TabTri.SetValue(Tab->Value(i),i);
260 Tab->ChangeArray1()=TabTri;
263 //---------------------------------------------------------
264 // Fonction : ProjectCurve
265 //---------------------------------------------------------
266 Handle(Geom2d_Curve) GeomPlate_BuildPlateSurface::ProjectCurve(const Handle(Adaptor3d_HCurve)& Curv)
267 { // Projection d'une courbe sur un plan
268 Handle(Geom2d_Curve) Curve2d ;
269 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
272 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTol3d/10, myTol3d/10);
274 Standard_Real Udeb, Ufin, ProjUdeb, ProjUfin;
275 Udeb = Curv->FirstParameter();
276 Ufin = Curv->LastParameter();
277 Projector.Bounds( 1, ProjUdeb, ProjUfin );
279 if (Projector.NbCurves() != 1 ||
280 Abs( Udeb-ProjUdeb ) > Precision::PConfusion() ||
281 Abs( Ufin-ProjUfin ) > Precision::PConfusion())
283 if (Projector.IsSinglePnt(1, P2d))
285 //solution ponctuelles
286 TColgp_Array1OfPnt2d poles(1, 2);
288 Curve2d = new (Geom2d_BezierCurve) (poles);
292 Curve2d.Nullify(); // Pas de solution continue
294 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
299 GeomAbs_Shape Continuity = GeomAbs_C1;
300 Standard_Integer MaxDegree = 10, MaxSeg;
301 Standard_Real Udeb, Ufin;
302 Handle(ProjLib_HCompProjectedCurve) HProjector =
303 new ProjLib_HCompProjectedCurve();
304 HProjector->Set(Projector);
305 Projector.Bounds(1, Udeb, Ufin);
307 MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
308 Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d,
309 Continuity, MaxDegree, MaxSeg,
310 Standard_False, Standard_True);
312 Curve2d = appr.Curve2d();
317 sprintf(name,"proj_%d",++NbProj);
318 DrawTrSurf::Set(name, Curve2d);
323 //---------------------------------------------------------
324 // Fonction : ProjectedCurve
325 //---------------------------------------------------------
326 Handle(Adaptor2d_HCurve2d) GeomPlate_BuildPlateSurface::ProjectedCurve( Handle(Adaptor3d_HCurve)& Curv)
327 { // Projection d'une courbe sur la surface d'init
329 Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(mySurfInit);
331 ProjLib_CompProjectedCurve Projector(hsur, Curv, myTolU/10, myTolV/10);
332 Handle(ProjLib_HCompProjectedCurve) HProjector =
333 new ProjLib_HCompProjectedCurve();
335 if (Projector.NbCurves() != 1) {
337 HProjector.Nullify(); // Pas de solution continue
339 cout << "BuildPlateSurace :: Pas de projection continue" << endl;
344 Standard_Real First1,Last1,First2,Last2;
345 First1=Curv->FirstParameter();
346 Last1 =Curv->LastParameter();
347 Projector.Bounds(1,First2,Last2);
349 if (Abs(First1-First2) <= Max(myTolU,myTolV) &&
350 Abs(Last1-Last2) <= Max(myTolU,myTolV))
353 HProjector->Set(Projector);
354 HProjector = Handle(ProjLib_HCompProjectedCurve)::
355 DownCast(HProjector->Trim(First2,Last2,Precision::PConfusion()));
359 HProjector.Nullify(); // Pas de solution continue
361 cout << "BuildPlateSurace :: Pas de projection complete" << endl;
368 //---------------------------------------------------------
369 // Fonction : ProjectPoint
370 //---------------------------------------------------------
371 // Projete une point sur la surface d'init
372 //---------------------------------------------------------
373 gp_Pnt2d GeomPlate_BuildPlateSurface::ProjectPoint(const gp_Pnt &p3d)
376 Standard_Integer nearest = 1;
377 if( myProj.NbExt() > 1)
379 Standard_Real dist2mini = myProj.SquareDistance(1);
380 for (Standard_Integer i=2; i<=myProj.NbExt();i++)
382 if (myProj.SquareDistance(i) < dist2mini)
384 dist2mini = myProj.SquareDistance(i);
389 P=myProj.Point(nearest);
397 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
398 // =========================================================
399 // M E T H O D E S P U B L I Q U E S
400 // =========================================================
401 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
402 //---------------------------------------------------------
404 //---------------------------------------------------------
405 // Initialise les contraintes lineaires et ponctuelles
406 //---------------------------------------------------------
407 void GeomPlate_BuildPlateSurface::Init()
408 { myLinCont->Clear();
410 myPntCont = new GeomPlate_HSequenceOfPointConstraint;
411 myLinCont = new GeomPlate_HSequenceOfCurveConstraint;
414 //---------------------------------------------------------
415 // Fonction : LoadInitSurface
416 //---------------------------------------------------------
417 // Charge la surface initiale
418 //---------------------------------------------------------
419 void GeomPlate_BuildPlateSurface::LoadInitSurface(const Handle(Geom_Surface)& Surf)
421 mySurfInitIsGive=Standard_True;
424 //---------------------------------------------------------
426 //---------------------------------------------------------
427 //---------------------------------------------------------
428 // Ajout d'une contrainte lineaire
429 //---------------------------------------------------------
430 void GeomPlate_BuildPlateSurface::
431 Add(const Handle(GeomPlate_CurveConstraint)& Cont)
432 { myLinCont->Append(Cont);
435 void GeomPlate_BuildPlateSurface::SetNbBounds( const Standard_Integer NbBounds )
437 myNbBounds = NbBounds;
440 //---------------------------------------------------------
442 //---------------------------------------------------------
443 //---------------------------------------------------------
444 // Ajout d'une contrainte ponctuelle
445 //---------------------------------------------------------
446 void GeomPlate_BuildPlateSurface::
447 Add(const Handle(GeomPlate_PointConstraint)& Cont)
449 myPntCont->Append(Cont);
452 //---------------------------------------------------------
454 // Calcul la surface de remplissage avec les contraintes chargees
455 //---------------------------------------------------------
456 void GeomPlate_BuildPlateSurface::Perform()
460 OSD_Chronometer Chrono;
466 myNbBounds = myLinCont->Length();
469 //=====================================================================
470 //Declaration des variables.
471 //=====================================================================
472 Standard_Integer NTLinCont = myLinCont->Length(),
473 NTPntCont = myPntCont->Length(), NbBoucle=0;
474 // La variable NTPoint peut etre enlevee
475 Standard_Boolean Fini=Standard_True;
476 if ((NTLinCont+NTPntCont)==0)
477 Standard_RangeError::Raise("GeomPlate : The number of constraints is null.");
479 //======================================================================
481 //======================================================================
482 if (!mySurfInitIsGive)
487 { // Tableau des permutations pour conserver l'ordre initial voir TrierTab
488 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
489 for (Standard_Integer l=1;l<=NTLinCont;l++)
490 myInitOrder->SetValue(l,l);
491 if (!CourbeJointive(myTol3d))
492 {// Standard_Failure::Raise("Curves are not joined");
494 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
497 TrierTab(myInitOrder); // Reordonne le tableau des permutations
499 else if(NTLinCont > 0)//Patch
501 mySense = new TColStd_HArray1OfInteger( 1, NTLinCont, 0 );
502 myInitOrder = new TColStd_HArray1OfInteger( 1, NTLinCont, 1 );
506 Standard_Real u1,v1,u2,v2;
507 mySurfInit->Bounds(u1,v1,u2,v2);
508 GeomAdaptor_Surface Surf(mySurfInit);
509 myTolU = Surf.UResolution(myTol3d);
510 myTolV = Surf.VResolution(myTol3d);
511 myProj.Initialize(Surf,u1,v1,u2,v2,
514 //======================================================================
515 // Projection des courbes
516 //======================================================================
518 Standard_Boolean Ok = Standard_True;
519 for (i = 1; i <= NTLinCont; i++)
520 if(myLinCont->Value(i)->Curve2dOnSurf().IsNull())
522 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
523 if (Curve2d.IsNull())
528 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
532 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
537 mySurfInit = App.Surface();
539 mySurfInit->Bounds(u1,v1,u2,v2);
540 GeomAdaptor_Surface Surf(mySurfInit);
541 myTolU = Surf.UResolution(myTol3d);
542 myTolV = Surf.VResolution(myTol3d);
543 myProj.Initialize(Surf,u1,v1,u2,v2,
547 for (i = 1; i <= NTLinCont; i++)
549 Handle( Geom2d_Curve ) Curve2d = ProjectCurve( myLinCont->Value(i)->Curve3d() );
550 if (Curve2d.IsNull())
555 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( Curve2d );
559 mySurfInit = myPlanarSurfInit;
561 mySurfInit->Bounds(u1,v1,u2,v2);
562 GeomAdaptor_Surface Surf(mySurfInit);
563 myTolU = Surf.UResolution(myTol3d);
564 myTolV = Surf.VResolution(myTol3d);
565 myProj.Initialize(Surf,u1,v1,u2,v2,
568 for (i = 1; i <= NTLinCont; i++)
569 myLinCont->ChangeValue(i)->
570 SetCurve2dOnSurf(ProjectCurve( myLinCont->Value(i)->Curve3d() ) );
572 else { // Project the points
573 for ( i=1;i<=NTPntCont;i++) {
575 myPntCont->Value(i)->D0(P);
576 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
581 //======================================================================
582 // Projection des points
583 //======================================================================
584 for ( i=1;i<=NTPntCont;i++) {
585 if (! myPntCont->Value(i)->HasPnt2dOnSurf()) {
587 myPntCont->Value(i)->D0(P);
588 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
592 //======================================================================
593 // Nbre de point par courbe
594 //======================================================================
595 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
598 //======================================================================
599 // Gestion des incompatibilites entre courbes
600 //======================================================================
601 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
602 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
603 if (NTLinCont != 0) {
604 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
605 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
606 Intersect(PntInter, PntG1G1);
609 //======================================================================
610 // Boucle pour obtenir une meilleur surface
611 //======================================================================
613 myFree = !myIsLinear;
618 if (Affich && NbBoucle) {
619 cout<<"Resultats boucle"<< NbBoucle << endl;
620 cout<<"DistMax="<<myG0Error<<endl;
622 cout<<"AngleMax="<<myG1Error<<endl;
624 cout<<"CourbMax="<<myG2Error<<endl;
629 { //====================================================================
630 // Calcul le nombre de point total et le maximum de points par courbe
631 //====================================================================
632 Standard_Integer NPointMax=0;
633 for (Standard_Integer i=1;i<=NTLinCont;i++)
634 if ((myLinCont->Value(i)->NbPoints())>NPointMax)
635 NPointMax=(Standard_Integer )( myLinCont->Value(i)->NbPoints());
636 //====================================================================
637 // Discretisation des courbes
638 //====================================================================
639 Discretise(PntInter, PntG1G1);
640 //====================================================================
641 //Preparation des points de contrainte pour plate
642 //====================================================================
643 LoadCurve( NbBoucle );
644 if ( myPntCont->Length() != 0)
645 LoadPoint( NbBoucle );
646 //====================================================================
647 //Resolution de la surface
648 //====================================================================
649 myPlate.SolveTI(myDegree, ComputeAnisotropie());
650 if (!myPlate.IsDone())
651 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
652 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
653 Standard_Real Umin,Umax,Vmin,Vmax;
654 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
655 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
657 Fini = VerifSurface(NbBoucle);
658 if ((NbBoucle >= myNbIter)&&(!Fini))
661 cout<<"Warning objectif non atteint"<<endl;
663 Fini = Standard_True;
666 if ((NTPntCont != 0)&&(Fini))
667 { Standard_Real di,an,cu;
668 VerifPoints(di,an,cu);
672 { LoadPoint( NbBoucle );
673 //====================================================================
674 //Resolution de la surface
675 //====================================================================
676 myPlate.SolveTI(myDegree, ComputeAnisotropie());
677 if (!myPlate.IsDone())
678 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
679 myGeomPlateSurface = new GeomPlate_Surface(mySurfInit,myPlate);
680 Standard_Real Umin,Umax,Vmin,Vmax;
681 myPlate.UVBox(Umin,Umax,Vmin,Vmax);
682 myGeomPlateSurface->SetBounds(Umin,Umax,Vmin,Vmax);
683 Fini = Standard_True;
684 Standard_Real di,an,cu;
685 VerifPoints(di,an,cu);
687 } while (!Fini); // Fin boucle pour meilleur surface
690 { cout<<"======== Resultats globaux ==========="<<endl;
691 cout<<"DistMax="<<myG0Error<<endl;
693 cout<<"AngleMax="<<myG1Error<<endl;
695 cout<<"CourbMax="<<myG2Error<<endl;
700 cout<<"*** FIN DE GEOMPLATE ***"<<endl;
701 cout<<"Temps de calcul : "<<Tps<<endl;
702 cout<<"Nombre de boucle : "<<NbBoucle<<endl;
706 //---------------------------------------------------------
707 // fonction : EcartContraintesMIL
708 //---------------------------------------------------------
709 void GeomPlate_BuildPlateSurface::
710 EcartContraintesMil ( const Standard_Integer c,
711 Handle(TColStd_HArray1OfReal)& d,
712 Handle(TColStd_HArray1OfReal)& an,
713 Handle(TColStd_HArray1OfReal)& courb)
715 Standard_Integer NbPt=myParCont->Value(c).Length();
720 NbPt=myParCont->Value(c).Length();
721 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
723 gp_Pnt2d P2d;Standard_Integer i;
724 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(c);
725 switch (LinCont->Order())
727 for (i=1; i<NbPt; i++)
728 { U = ( myParCont->Value(c).Value(i) +
729 myParCont->Value(c).Value(i+1) )/2;
731 if (!LinCont->ProjectedCurve().IsNull())
732 P2d = LinCont->ProjectedCurve()->Value(U);
734 { if (!LinCont->Curve2dOnSurf().IsNull())
735 P2d = LinCont->Curve2dOnSurf()->Value(U);
737 P2d = ProjectPoint(Pi);
739 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
742 d->ChangeValue(i) = Pf.Distance(Pi);
746 for (i=1; i<NbPt; i++)
747 { U = ( myParCont->Value(c).Value(i) +
748 myParCont->Value(c).Value(i+1) )/2;
749 LinCont->D1(U, Pi, v1i, v2i);
750 if (!LinCont->ProjectedCurve().IsNull())
751 P2d = LinCont->ProjectedCurve()->Value(U);
753 { if (!LinCont->Curve2dOnSurf().IsNull())
754 P2d = LinCont->Curve2dOnSurf()->Value(U);
756 P2d = ProjectPoint(Pi);
758 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
759 d->ChangeValue(i) = Pf.Distance(Pi);
760 v3i = v1i^v2i; v3f=v1f^v2f;
761 Standard_Real angle=v3f.Angle(v3i);
763 an->ChangeValue(i) = M_PI -angle;
765 an->ChangeValue(i) = angle;
770 Handle(Geom_Surface) Splate;
771 Splate = Handle(Geom_Surface)::DownCast(myGeomPlateSurface);
772 LocalAnalysis_SurfaceContinuity CG2;
773 for (i=1; i<NbPt; i++)
774 { U = ( myParCont->Value(c).Value(i) +
775 myParCont->Value(c).Value(i+1) )/2;
777 if (!LinCont->ProjectedCurve().IsNull())
778 P2d = LinCont->ProjectedCurve()->Value(U);
780 { if (!LinCont->Curve2dOnSurf().IsNull())
781 P2d = LinCont->Curve2dOnSurf()->Value(U);
783 P2d = ProjectPoint(Pi);
785 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
787 CG2.ComputeAnalysis(Prop, myLinCont->Value(c)->LPropSurf(U),
789 d->ChangeValue(i)=CG2.C0Value();
790 an->ChangeValue(i)=CG2.G1Angle();
791 courb->ChangeValue(i)=CG2.G2CurvatureGap();
799 //---------------------------------------------------------
800 // fonction : Disc2dContour
801 //---------------------------------------------------------
802 void GeomPlate_BuildPlateSurface::
803 Disc2dContour ( const Standard_Integer /*nbp*/,
804 TColgp_SequenceOfXY& Seq2d)
807 if (Seq2d.Length()!=4)
808 cout<<"nbp doit etre egal a 4 pour Disc2dContour"<<endl;
813 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
814 Standard_Integer NTCurve = myLinCont->Length();
815 Standard_Integer NTPntCont = myPntCont->Length();
819 Standard_Real u1,v1,u2,v2;
822 mySurfInit->Bounds(u1,v1,u2,v2);
823 GeomAdaptor_Surface Surf(mySurfInit);
824 myProj.Initialize(Surf,u1,v1,u2,v2,
827 for( i=1; i<=NTPntCont; i++)
828 if (myPntCont->Value(i)->Order()!=-1)
829 { P2d = myPntCont->Value(i)->Pnt2dOnSurf();
830 UV.SetX(P2d.Coord(1));
831 UV.SetY(P2d.Coord(2));
834 for(i=1; i<=NTCurve; i++)
836 Handle(GeomPlate_CurveConstraint) LinCont = myLinCont->Value(i);
837 if (LinCont->Order()!=-1)
838 { Standard_Integer NbPt=myParCont->Value(i).Length();
839 // premier point de contrainte (j=0)
840 if (!LinCont->ProjectedCurve().IsNull())
841 P2d = LinCont->ProjectedCurve()->Value(myParCont->Value(i).Value(1));
844 { if (!LinCont->Curve2dOnSurf().IsNull())
845 P2d = LinCont->Curve2dOnSurf()->Value(myParCont->Value(i).Value(1));
849 LinCont->D0(myParCont->Value(i).Value(1),PP);
850 P2d = ProjectPoint(PP);
854 UV.SetX(P2d.Coord(1));
855 UV.SetY(P2d.Coord(2));
857 for (Standard_Integer j=2; j<NbPt; j++)
858 { Standard_Real Uj=myParCont->Value(i).Value(j),
859 Ujp1=myParCont->Value(i).Value(j+1);
860 if (!LinCont->ProjectedCurve().IsNull())
861 P2d = LinCont->ProjectedCurve()->Value((Ujp1+3*Uj)/4);
864 { if (!LinCont->Curve2dOnSurf().IsNull())
865 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+3*Uj)/4);
869 LinCont->D0((Ujp1+3*Uj)/4,PP);
870 P2d = ProjectPoint(PP);
873 UV.SetX(P2d.Coord(1));
874 UV.SetY(P2d.Coord(2));
876 // point milieu precedent
877 if (!LinCont->ProjectedCurve().IsNull())
878 P2d = LinCont->ProjectedCurve()->Value((Ujp1+Uj)/2);
881 { if (!LinCont->Curve2dOnSurf().IsNull())
882 P2d = LinCont->Curve2dOnSurf()->Value((Ujp1+Uj)/2);
886 LinCont->D0((Ujp1+Uj)/2,PP);
887 P2d = ProjectPoint(PP);
891 UV.SetX(P2d.Coord(1));
892 UV.SetY(P2d.Coord(2));
894 // point 3/4 precedent
895 if (!LinCont->ProjectedCurve().IsNull())
896 P2d = LinCont->ProjectedCurve()->Value((3*Ujp1+Uj)/4);
899 { if (!LinCont->Curve2dOnSurf().IsNull())
900 P2d = LinCont->Curve2dOnSurf()->Value((3*Ujp1+Uj)/4);
904 LinCont->D0((3*Ujp1+Uj)/4,PP);
905 P2d = ProjectPoint(PP);
909 UV.SetX(P2d.Coord(1));
910 UV.SetY(P2d.Coord(2));
912 // point de contrainte courant
913 if (!LinCont->ProjectedCurve().IsNull())
914 P2d = LinCont->ProjectedCurve()->Value(Ujp1);
917 { if (!LinCont->Curve2dOnSurf().IsNull())
918 P2d = LinCont->Curve2dOnSurf()->Value(Ujp1);
922 LinCont->D0(Ujp1,PP);
923 P2d = ProjectPoint(PP);
927 UV.SetX(P2d.Coord(1));
928 UV.SetY(P2d.Coord(2));
935 //---------------------------------------------------------
936 // fonction : Disc3dContour
937 //---------------------------------------------------------
938 void GeomPlate_BuildPlateSurface::
939 Disc3dContour (const Standard_Integer /*nbp*/,
940 const Standard_Integer iordre,
941 TColgp_SequenceOfXYZ& Seq3d)
944 if (Seq3d.Length()!=4)
945 cout<<"nbp doit etre egal a 4 pour Disc3dContour"<<endl;
946 if (iordre!=0&&iordre!=1)
947 cout<<"iordre incorrect pour Disc3dContour"<<endl;
951 // echantillonnage en "cosinus" + 3 points sur chaque intervalle
952 Standard_Real u1,v1,u2,v2;
953 mySurfInit->Bounds(u1,v1,u2,v2);
954 GeomAdaptor_Surface Surf(mySurfInit);
955 myProj.Initialize(Surf,u1,v1,u2,v2,
956 Surf.UResolution(myTol3d),
957 Surf.VResolution(myTol3d));
958 Standard_Integer NTCurve = myLinCont->Length();
959 Standard_Integer NTPntCont = myPntCont->Length();
966 for( i=1; i<=NTPntCont; i++)
967 if (myPntCont->Value(i)->Order()!=-1)
969 { myPntCont->Value(i)->D0(P3d);
976 myPntCont->Value(i)->D1(P3d,v1h,v2h);
985 for(i=1; i<=NTCurve; i++)
986 if (myLinCont->Value(i)->Order()!=-1)
988 { Standard_Integer NbPt=myParCont->Value(i).Length();;
989 // premier point de contrainte (j=0)
990 // Standard_Integer NbPt=myParCont->Length();
992 myLinCont->Value(i)->D0(myParCont->Value(i).Value(1),P3d);
999 myLinCont->Value(i)->D1(myParCont->Value(i).Value(1),P3d,v1h,v2h);
1007 for (Standard_Integer j=2; j<NbPt; j++)
1008 { Standard_Real Uj=myParCont->Value(i).Value(j),
1009 Ujp1=myParCont->Value(i).Value(j+1);
1011 // point 1/4 precedent
1012 myLinCont->Value(i)->D0((Ujp1+3*Uj)/4,P3d);
1017 // point milieu precedent
1018 myLinCont->Value(i)->D0((Ujp1+Uj)/2,P3d);
1023 // point 3/4 precedent
1024 myLinCont->Value(i)->D0((3*Ujp1+Uj)/4,P3d);
1029 // point de contrainte courant
1030 myLinCont->Value(i)->D0(Ujp1,P3d);
1037 // point 1/4 precedent
1038 myLinCont->Value(i)->D1((Ujp1+3*Uj)/4,P3d,v1h,v2h);
1044 // point milieu precedent
1045 myLinCont->Value(i)->D1((Ujp1+Uj)/2,P3d,v1h,v2h);
1051 // point 3/4 precedent
1052 myLinCont->Value(i)->D1((3*Ujp1+Uj)/4,P3d,v1h,v2h);
1058 // point de contrainte courant
1059 myLinCont->Value(i)->D1(Ujp1,P3d,v1h,v2h);
1072 //---------------------------------------------------------
1073 // fonction : IsDone
1074 //---------------------------------------------------------
1075 Standard_Boolean GeomPlate_BuildPlateSurface::IsDone() const
1076 { return myPlate.IsDone();
1081 //---------------------------------------------------------
1082 // fonction : Surface
1083 //---------------------------------------------------------
1084 Handle(GeomPlate_Surface) GeomPlate_BuildPlateSurface::Surface() const
1085 { return myGeomPlateSurface ;
1088 //---------------------------------------------------------
1089 // fonction : SurfInit
1090 //---------------------------------------------------------
1091 Handle(Geom_Surface) GeomPlate_BuildPlateSurface::SurfInit() const
1092 { return mySurfInit ;
1096 //---------------------------------------------------------
1098 //---------------------------------------------------------
1099 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Sense() const
1100 { Standard_Integer NTCurve = myLinCont->Length();
1101 Handle(TColStd_HArray1OfInteger) Sens = new TColStd_HArray1OfInteger(1,
1103 for (Standard_Integer i=1; i<=NTCurve; i++)
1104 Sens->SetValue(i,mySense->Value(myInitOrder->Value(i)));
1110 //---------------------------------------------------------
1111 // fonction : Curve2d
1112 //---------------------------------------------------------
1113 Handle(TColGeom2d_HArray1OfCurve) GeomPlate_BuildPlateSurface::Curves2d() const
1114 { Standard_Integer NTCurve = myLinCont->Length();
1115 Handle(TColGeom2d_HArray1OfCurve) C2dfin =
1116 new TColGeom2d_HArray1OfCurve(1,NTCurve);
1118 for (Standard_Integer i=1; i<=NTCurve; i++)
1119 C2dfin->SetValue(i,myLinCont->Value(myInitOrder->Value(i))->Curve2dOnSurf());
1125 //---------------------------------------------------------
1127 //---------------------------------------------------------
1128 Handle(TColStd_HArray1OfInteger) GeomPlate_BuildPlateSurface::Order() const
1129 { Handle(TColStd_HArray1OfInteger) result=
1130 new TColStd_HArray1OfInteger(1,myLinCont->Length());
1131 for (Standard_Integer i=1;i<=myLinCont->Length();i++)
1132 result->SetValue(myInitOrder->Value(i),i);
1137 //---------------------------------------------------------
1138 // fonction : G0Error
1139 //---------------------------------------------------------
1140 Standard_Real GeomPlate_BuildPlateSurface::G0Error() const
1144 //---------------------------------------------------------
1145 // fonction : G1Error
1146 //---------------------------------------------------------
1147 Standard_Real GeomPlate_BuildPlateSurface::G1Error() const
1151 //---------------------------------------------------------
1152 // fonction : G2Error
1153 //---------------------------------------------------------
1154 Standard_Real GeomPlate_BuildPlateSurface::G2Error() const
1158 //=======================================================================
1159 //function : G0Error
1161 //=======================================================================
1163 Standard_Real GeomPlate_BuildPlateSurface::G0Error( const Standard_Integer Index )
1165 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1166 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1167 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1168 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1169 Standard_Real MaxDistance = 0.;
1170 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1171 if (tdistance->Value(i) > MaxDistance)
1172 MaxDistance = tdistance->Value(i);
1176 //=======================================================================
1177 //function : G1Error
1179 //=======================================================================
1181 Standard_Real GeomPlate_BuildPlateSurface::G1Error( const Standard_Integer Index )
1183 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1184 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1185 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1186 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1187 Standard_Real MaxAngle = 0.;
1188 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1189 if (tangle->Value(i) > MaxAngle)
1190 MaxAngle = tangle->Value(i);
1194 //=======================================================================
1195 //function : G2Error
1197 //=======================================================================
1199 Standard_Real GeomPlate_BuildPlateSurface::G2Error( const Standard_Integer Index )
1201 Handle( TColStd_HArray1OfReal ) tdistance = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1202 Handle( TColStd_HArray1OfReal ) tangle = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1203 Handle( TColStd_HArray1OfReal ) tcurvature = new TColStd_HArray1OfReal( 1, myNbPtsOnCur );
1204 EcartContraintesMil( Index, tdistance, tangle, tcurvature );
1205 Standard_Real MaxCurvature = 0.;
1206 for (Standard_Integer i = 1; i <= myNbPtsOnCur; i++)
1207 if (tcurvature->Value(i) > MaxCurvature)
1208 MaxCurvature = tcurvature->Value(i);
1209 return MaxCurvature;
1212 Handle(GeomPlate_CurveConstraint) GeomPlate_BuildPlateSurface::CurveConstraint( const Standard_Integer order) const
1214 return myLinCont->Value(order);
1216 Handle(GeomPlate_PointConstraint) GeomPlate_BuildPlateSurface::PointConstraint( const Standard_Integer order) const
1218 return myPntCont->Value(order);
1220 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1221 // =========================================================
1222 // M E T H O D E S P R I V E S
1223 // =========================================================
1224 //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
1226 //=======================================================================
1227 // function : CourbeJointive
1228 // purpose : Effectue un chainage des courbes pour pouvoir calculer
1229 // la surface d'init avec la methode du flux maxi.
1230 // Retourne vrai si il s'agit d'un contour ferme.
1231 //=======================================================================
1233 Standard_Boolean GeomPlate_BuildPlateSurface::
1234 CourbeJointive(const Standard_Real tolerance)
1235 { Standard_Integer nbf = myLinCont->Length();
1236 Standard_Real Ufinal1,Uinit1,Ufinal2,Uinit2;
1237 mySense = new TColStd_HArray1OfInteger(1,nbf,0);
1238 Standard_Boolean result=Standard_True;
1239 Standard_Integer j=1,i;
1242 while (j <= (myNbBounds-1))
1244 Standard_Integer a=0;
1247 { result = Standard_False;
1251 { if (i > myNbBounds)
1252 { result = Standard_False;
1257 Uinit1=myLinCont->Value(j)->FirstParameter();
1258 Ufinal1=myLinCont->Value(j)->LastParameter();
1259 Uinit2=myLinCont->Value(i)->FirstParameter();
1260 Ufinal2=myLinCont->Value(i)->LastParameter();
1261 if (mySense->Value(j)==1)
1263 myLinCont->Value(j)->D0(Ufinal1,P1);
1264 myLinCont->Value(i)->D0(Uinit2,P2);
1265 if (P1.Distance(P2)<tolerance)
1267 Handle(GeomPlate_CurveConstraint) tampon = myLinCont->Value(j+1);
1268 myLinCont->SetValue(j+1,myLinCont->Value(i));
1269 myLinCont->SetValue(i,tampon);
1270 Standard_Integer Tmp=myInitOrder->Value(j+1);
1271 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1272 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1273 myInitOrder->SetValue(i,Tmp);
1278 mySense->SetValue(j+1,0);
1282 { myLinCont->Value(i)->D0(Ufinal2,P2);
1284 if (P1.Distance(P2)<tolerance)
1286 Handle(GeomPlate_CurveConstraint) tampon =
1287 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 //Voir fonction TrierTab pour le fonctionnement de myInitOrder
1292 myInitOrder->SetValue(j+1,myInitOrder->Value(i));
1293 myInitOrder->SetValue(i,Tmp);
1296 mySense->SetValue(j+1,1);
1304 Uinit1=myLinCont->Value( myNbBounds )->FirstParameter();
1305 Ufinal1=myLinCont->Value( myNbBounds )->LastParameter();
1306 Uinit2=myLinCont->Value(1)->FirstParameter();
1307 Ufinal2=myLinCont->Value(1)->LastParameter();
1308 myLinCont->Value( myNbBounds )->D0(Ufinal1,P1);
1309 myLinCont->Value(1)->D0(Uinit2,P2);
1310 if ((mySense->Value( myNbBounds )==0)
1311 &&(P1.Distance(P2)<tolerance))
1313 return ((Standard_True)&&(result));
1315 myLinCont->Value( myNbBounds )->D0(Uinit1,P1);
1316 if ((mySense->Value( myNbBounds )==1)
1317 &&(P1.Distance(P2)<tolerance))
1319 return ((Standard_True)&&(result));
1321 else return Standard_False;
1325 //-------------------------------------------------------------------------
1326 // fonction : ComputeSurfInit
1327 //-------------------------------------------------------------------------
1328 // Calcul la surface d'init soit par la methode du flux maxi soit par
1329 // la methode du plan d'inertie si le contour n'est pas ferme ou si
1330 // il y a des contraintes ponctuelles
1331 //-------------------------------------------------------------------------
1333 void GeomPlate_BuildPlateSurface::ComputeSurfInit()
1335 Standard_Integer nopt=2, popt=2, Np=1;
1336 Standard_Boolean isHalfSpace = Standard_True;
1337 Standard_Real LinTol = 0.001, AngTol = 0.001; //AngTol = 0.0001; //LinTol = 0.0001
1339 // Option pour le calcul du plan initial
1340 Standard_Integer NTLinCont = myLinCont->Length(), NTPntCont = myPntCont->Length();
1341 // Tableau des permutation pour conserver l'ordre initial voir TrierTab
1342 if (NTLinCont != 0) {
1343 myInitOrder = new TColStd_HArray1OfInteger(1,NTLinCont);
1344 for (Standard_Integer i = 1; i <= NTLinCont; i++)
1345 myInitOrder->SetValue( i, i );
1348 Standard_Boolean CourbeJoint = (NTLinCont != 0) && CourbeJointive (myTol3d);
1349 if (CourbeJoint && IsOrderG1())
1352 // Tableau contenant le nuage de point pour le calcul du plan
1353 Standard_Integer NbPoint = 20, Discr = NbPoint/4, pnum = 0;
1354 Handle( TColgp_HArray1OfPnt ) Pts = new TColgp_HArray1OfPnt( 1, (NbPoint+1)*NTLinCont+NTPntCont );
1355 TColgp_SequenceOfVec Vecs, NewVecs;
1356 GeomPlate_SequenceOfAij Aset;
1357 Standard_Real Uinit, Ufinal, Uif;
1359 Standard_Integer i ;
1360 for ( i = 1; i <= NTLinCont; i++)
1362 Standard_Integer Order = myLinCont->Value(i)->Order();
1366 Uinit = myLinCont->Value(i)->FirstParameter();
1367 Ufinal = myLinCont->Value(i)->LastParameter();
1368 Uif = Ufinal - Uinit;
1369 if (mySense->Value(i) == 1)
1375 gp_Vec Vec1, Vec2, Normal;
1376 Standard_Boolean ToReverse = Standard_False;
1377 if (i > 1 && Order >= GeomAbs_G1)
1380 myLinCont->Value(i)->D1( Uinit, P, Vec1, Vec2 );
1381 Normal = Vec1 ^ Vec2;
1382 if (LastVec.IsOpposite( Normal, AngTol ))
1383 ToReverse = Standard_True;
1386 for (Standard_Integer j = 0; j <= NbPoint; j++)
1387 { // Nombre de point par courbe = 20
1388 // Repartition lineaire
1389 Standard_Real Inter = j*Uif/(NbPoint);
1390 if (Order < GeomAbs_G1 || j % Discr != 0)
1391 myLinCont->Value(i)->D0( Uinit+Inter, Pts->ChangeValue(++pnum) );
1394 myLinCont->Value(i)->D1( Uinit+Inter, Pts->ChangeValue(++pnum), Vec1, Vec2 );
1395 Normal = Vec1 ^ Vec2;
1399 Standard_Boolean isNew = Standard_True;
1400 Standard_Integer k ;
1401 for ( k = 1; k <= Vecs.Length(); k++)
1402 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1404 isNew = Standard_False;
1408 for (k = 1; k <= NewVecs.Length(); k++)
1409 if (NewVecs(k).IsEqual( Normal, LinTol, AngTol ))
1411 isNew = Standard_False;
1415 NewVecs.Append( Normal );
1418 if (Order >= GeomAbs_G1)
1420 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1425 } //for (i = 1; i <= NTLinCont; i++)
1429 for (i = 1; i <= NTPntCont; i++)
1431 Standard_Integer Order = myPntCont->Value(i)->Order();
1434 gp_Vec Vec1, Vec2, Normal;
1435 if (Order < GeomAbs_G1)
1436 myPntCont->Value(i)->D0( Pts->ChangeValue(++pnum) );
1439 myPntCont->Value(i)->D1( Pts->ChangeValue(++pnum), Vec1, Vec2 );
1440 Normal = Vec1 ^ Vec2;
1442 Standard_Boolean isNew = Standard_True;
1443 for (Standard_Integer k = 1; k <= Vecs.Length(); k++)
1444 if (Vecs(k).IsEqual( Normal, LinTol, AngTol ))
1446 isNew = Standard_False;
1451 NewVecs.Append( Normal );
1452 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1455 NewVecs(1).Reverse();
1456 isHalfSpace = GeomPlate_BuildAveragePlane::HalfSpace( NewVecs, Vecs, Aset, LinTol, AngTol );
1462 } //for (i = 1; i <= NTPntCont; i++)
1466 Standard_Boolean NullExist = Standard_True;
1469 NullExist = Standard_False;
1470 for (i = 1; i <= Vecs.Length(); i++)
1471 if (Vecs(i).SquareMagnitude() == 0.)
1473 NullExist = Standard_True;
1478 GeomPlate_BuildAveragePlane BAP( Vecs, Pts );
1479 Standard_Real u1,u2,v1,v2;
1480 BAP.MinMaxBox(u1,u2,v1,v2);
1481 // On agrandit le bazar pour les projections
1482 Standard_Real du = u2 - u1;
1483 Standard_Real dv = v2 - v1;
1484 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1485 mySurfInit = new Geom_RectangularTrimmedSurface( BAP.Plane(), u1,u2,v1,v2 );
1487 } //if (isHalfSpace)
1491 cout<<endl<<"Normals are not in half space"<<endl<<endl;
1493 myIsLinear = Standard_False;
1496 } //if (NTLinCont != 0 && (CourbeJoint = CourbeJointive( myTol3d )) && IsOrderG1())
1499 TrierTab( myInitOrder ); // Reordonne le tableau des permutations
1503 if ( NTPntCont != 0)
1504 nopt = 1; //Calcul par la methode du plan d'inertie
1505 else if (!CourbeJoint || NTLinCont != myNbBounds)
1506 {// Standard_Failure::Raise("Curves are not joined");
1508 cout<<"WARNING : Courbes non jointives a "<<myTol3d<<" pres"<<endl;
1513 Standard_Real LenT=0;
1514 Standard_Integer Npt=0;
1515 Standard_Integer NTPoint=20*NTLinCont;
1516 Standard_Integer i ;
1517 for ( i=1;i<=NTLinCont;i++)
1518 LenT+=myLinCont->Value(i)->Length();
1519 for (i=1;i<=NTLinCont;i++)
1520 { Standard_Integer NbPoint= (Standard_Integer )( NTPoint*(myLinCont->Value(i)->Length())/LenT);
1525 // Tableau contenant le nuage de point pour le calcul du plan
1526 Handle(TColgp_HArray1OfPnt) Pts = new TColgp_HArray1OfPnt(1,20*NTLinCont+NTPntCont);
1527 Standard_Integer NbPoint=20;
1528 Standard_Real Uinit,Ufinal, Uif;
1529 for ( i=1;i<=NTLinCont;i++)
1530 { Uinit=myLinCont->Value(i)->FirstParameter();
1531 Ufinal=myLinCont->Value(i)->LastParameter();
1533 if (mySense->Value(i) == 1)
1537 for (Standard_Integer j=0; j<NbPoint; j++)
1538 { // Nombre de point par courbe = 20
1539 // Repartition lineaire
1540 Standard_Real Inter=j*Uif/(NbPoint);
1542 myLinCont->Value(i)->D0(Uinit+Inter,P);
1543 Pts->SetValue(Np++,P);
1546 for (i=1;i<=NTPntCont;i++)
1548 myPntCont->Value(i)->D0(P);
1549 Pts->SetValue(Np++,P);
1553 GeomPlate_BuildAveragePlane BAP( Pts, NbPoint*myNbBounds, myTol3d/1000, popt, nopt );
1554 if (!BAP.IsPlane()) Standard_Failure::Raise("the initial surface is not a plane.");
1555 Standard_Real u1,u2,v1,v2;
1556 BAP.MinMaxBox(u1,u2,v1,v2);
1557 // On agrandit le bazar pour les projections
1558 Standard_Real du = u2 - u1;
1559 Standard_Real dv = v2 - v1;
1560 u1 -= du; u2 += du; v1 -= dv; v2 += dv;
1561 mySurfInit = new Geom_RectangularTrimmedSurface(BAP.Plane(),u1,u2,v1,v2);
1564 //Comparing metrics of curves and projected curves
1565 if (NTLinCont != 0 && myIsLinear)
1567 Handle( Geom_Surface ) InitPlane =
1568 (Handle( Geom_RectangularTrimmedSurface )::DownCast(mySurfInit))->BasisSurface();
1570 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;
1571 Handle( GeomAdaptor_HSurface ) hsur =
1572 new GeomAdaptor_HSurface( InitPlane );
1573 Standard_Integer NbPoint = 20;
1575 // gp_Vec DerC, DerCproj, DU, DV;
1580 for (Standard_Integer i = 1; i <= NTLinCont && myIsLinear; i++)
1582 Standard_Real FirstPar = myLinCont->Value(i)->FirstParameter();
1583 Standard_Real LastPar = myLinCont->Value(i)->LastParameter();
1584 Standard_Real Uif = (LastPar - FirstPar)/(NbPoint);
1586 Handle( Adaptor3d_HCurve ) Curve = myLinCont->Value(i)->Curve3d();
1587 ProjLib_CompProjectedCurve Projector( hsur, Curve, myTol3d, myTol3d );
1588 Handle( ProjLib_HCompProjectedCurve ) ProjCurve =
1589 new ProjLib_HCompProjectedCurve();
1590 ProjCurve->Set( Projector );
1591 Adaptor3d_CurveOnSurface AProj(ProjCurve, hsur);
1594 gp_Vec DerC, DerCproj;
1595 for (Standard_Integer j = 1 ; j < NbPoint && myIsLinear; j++)
1597 Standard_Real Inter = FirstPar + j*Uif;
1598 Curve->D1(Inter, P, DerC);
1599 AProj.D1(Inter, P, DerCproj);
1601 Standard_Real A1 = DerC.Magnitude();
1602 Standard_Real A2 = DerCproj.Magnitude();
1609 if (Ratio > R1 || Ratio < R2)
1611 myIsLinear = Standard_False;
1618 cout <<"Metrics are too different :"<< Ratio<<endl;
1620 // myIsLinear = Standard_True; // !!
1621 } //comparing metrics of curves and projected curves
1626 myPlanarSurfInit = mySurfInit;
1630 sprintf(name,"planinit_%d",NbPlan+1);
1631 DrawTrSurf::Set(name, mySurfInit);
1634 Standard_Real u1,v1,u2,v2;
1635 mySurfInit->Bounds(u1,v1,u2,v2);
1636 GeomAdaptor_Surface Surf(mySurfInit);
1637 myTolU = Surf.UResolution(myTol3d);
1638 myTolV = Surf.VResolution(myTol3d);
1639 myProj.Initialize(Surf,u1,v1,u2,v2,
1642 //======================================================================
1643 // Projection des courbes
1644 //======================================================================
1646 for (i = 1; i <= NTLinCont; i++)
1647 if (myLinCont->Value(i)->Curve2dOnSurf().IsNull())
1648 myLinCont->ChangeValue(i)->SetCurve2dOnSurf(ProjectCurve(myLinCont->Value(i)->Curve3d()));
1650 //======================================================================
1651 // Projection des points
1652 //======================================================================
1653 for (i = 1; i<=NTPntCont; i++)
1655 myPntCont->Value(i)->D0(P);
1656 if (!myPntCont->Value(i)->HasPnt2dOnSurf())
1657 myPntCont->ChangeValue(i)->SetPnt2dOnSurf(ProjectPoint(P));
1660 //======================================================================
1661 // Nbre de point par courbe
1662 //======================================================================
1663 if ((NTLinCont !=0)&&(myNbPtsOnCur!=0))
1666 //======================================================================
1667 // Gestion des incompatibilites entre courbes
1668 //======================================================================
1669 Handle(GeomPlate_HArray1OfSequenceOfReal) PntInter;
1670 Handle(GeomPlate_HArray1OfSequenceOfReal) PntG1G1;
1673 PntInter = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1674 PntG1G1 = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1675 Intersect(PntInter, PntG1G1);
1678 //====================================================================
1679 // Discretisation des courbes
1680 //====================================================================
1681 Discretise(PntInter, PntG1G1);
1682 //====================================================================
1683 //Preparation des points de contrainte pour plate
1684 //====================================================================
1686 if (myPntCont->Length() != 0)
1688 //====================================================================
1689 //Resolution de la surface
1690 //====================================================================
1691 myPlate.SolveTI(2, ComputeAnisotropie());
1692 if (!myPlate.IsDone())
1693 Standard_Failure::Raise("GeomPlate : abort calcul of Plate.");
1695 myGeomPlateSurface = new GeomPlate_Surface( mySurfInit, myPlate );
1697 GeomPlate_MakeApprox App(myGeomPlateSurface, myTol3d,
1701 mySurfInit = App.Surface();
1703 mySurfInitIsGive = Standard_True;
1704 myPlate.Init(); // Reset
1706 for (i=1;i<=NTLinCont;i++)
1708 Handle( Geom2d_Curve ) NullCurve;
1709 NullCurve.Nullify();
1710 myLinCont->ChangeValue(i)->SetCurve2dOnSurf( NullCurve);
1717 sprintf(name,"surfinit_%d",++NbPlan);
1718 DrawTrSurf::Set(name, mySurfInit);
1723 //---------------------------------------------------------
1724 // fonction : Intersect
1725 //---------------------------------------------------------
1726 // Recherche les intersections entre les courbe 2d
1727 // Si intersection et compatible( dans le cas G1-G1)
1728 // enleve le point sur une des deux courbes
1729 //---------------------------------------------------------
1730 void GeomPlate_BuildPlateSurface::
1731 Intersect(Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1732 Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1734 Standard_Integer NTLinCont = myLinCont->Length();
1735 Geom2dInt_GInter Intersection;
1736 Geom2dAdaptor_Curve Ci, Cj;
1737 IntRes2d_IntersectionPoint int2d;
1741 // if (!mySurfInitIsGive)
1742 for (Standard_Integer i=1;i<=NTLinCont;i++)
1744 //Standard_Real NbPnt_i=myLinCont->Value(i)->NbPoints();
1745 // Cherche l'intersection avec chaque courbe y compris elle meme.
1746 Ci.Load(myLinCont->Value(i)->Curve2dOnSurf());
1747 for(Standard_Integer j=i; j<=NTLinCont; j++)
1749 Cj.Load(myLinCont->Value(j)->Curve2dOnSurf());
1751 Intersection.Perform(Ci, myTol2d*10, myTol2d*10);
1753 Intersection.Perform(Ci, Cj, myTol2d*10, myTol2d*10);
1755 if (!Intersection.IsEmpty())
1756 { // il existe une intersection
1757 Standard_Integer nbpt = Intersection.NbPoints();
1758 // nombre de point d'intersection
1759 for (Standard_Integer k = 1; k <= nbpt; k++)
1760 { int2d = Intersection.Point(k);
1761 myLinCont->Value(i)->D0(int2d.ParamOnFirst(),P1);
1762 myLinCont->Value(j)->D0(int2d.ParamOnSecond(),P2);
1766 cout << " Intersection "<< k << " entre " << i
1767 << " &" << j << endl;
1768 cout <<" Distance = "<< P1.Distance(P2) << endl;
1771 if (P1.Distance( P2 ) < myTol3d)
1772 { // L'intersection 2d correspond a des points 3d proches
1773 // On note l'intervalle dans lequel il faudra enlever
1774 // un point pour eviter les doublons ce qui fait une
1775 // erreur dans plate. le point sur la courbe i est enleve
1776 // on conserve celui de la courbe j
1777 // la longueur de l'intervalle est une longueur 2d
1778 // correspondant en 3d a myTol3d
1779 Standard_Real tolint = Ci.Resolution(myTol3d);
1780 Ci.D1(int2d.ParamOnFirst(),P2d, V2d);
1781 Standard_Real aux = V2d.Magnitude();
1785 if (aux > 100*tolint) tolint*=100;
1790 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1791 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1793 if ( (myLinCont->Value(i)->Order()==1)
1794 &&(myLinCont->Value(j)->Order()==1))
1795 { gp_Vec v11,v12,v13,v14,v15,v16,v21,v22,v23,v24,v25,v26;
1796 myLinCont->Value(i)->D2( int2d.ParamOnFirst(), P1, v11, v12, v13, v14, v15 );
1797 myLinCont->Value(j)->D2( int2d.ParamOnSecond(), P2, v21, v22, v23, v24, v25 );
1798 v16=v11^v12;v26=v21^v22;
1799 Standard_Real ant=v16.Angle(v26);
1802 if ((Abs(v16*v15-v16*v25)>(myTol3d/1000))
1803 ||(Abs(ant)>myTol3d/1000))
1804 // Pas compatible ==> on enleve une zone en
1805 // contrainte G1 correspondant
1806 // a une tolerance 3D de 0.01
1807 { Standard_Real coin;
1808 Standard_Real Tol= 100 * myTol3d;
1812 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1, V1);
1813 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2, V2);
1817 if (Abs(Abs(A1)-M_PI)<myTolAng) Tol = 100000 * myTol3d;
1819 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1820 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1823 coin = Ci.Resolution(Tol);
1824 Standard_Real Par1=int2d.ParamOnFirst()-coin,
1825 Par2=int2d.ParamOnFirst()+coin;
1826 // Stockage de l'intervalle pour la courbe i
1827 PntG1G1->ChangeValue(i).Append(Par1);
1828 PntG1G1->ChangeValue(i).Append(Par2);
1829 coin = Cj.Resolution(Tol);
1830 Par1=int2d.ParamOnSecond()-coin;
1831 Par2=int2d.ParamOnSecond()+coin;
1832 // Stockage de l'intervalle pour la courbe j
1833 PntG1G1->ChangeValue(j).Append(Par1);
1834 PntG1G1->ChangeValue(j).Append(Par2);
1838 if ((myLinCont->Value(i)->Order()==0 && myLinCont->Value(j)->Order()==1) ||
1839 (myLinCont->Value(i)->Order()==1 && myLinCont->Value(j)->Order()==0))
1841 gp_Vec vec, vecU, vecV, N;
1842 if (myLinCont->Value(i)->Order() == 0)
1844 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(i)->Curve3d();
1845 theCurve->D1( int2d.ParamOnFirst(), P1, vec );
1846 myLinCont->Value(j)->D1( int2d.ParamOnSecond(), P2, vecU, vecV );
1850 Handle( Adaptor3d_HCurve ) theCurve = myLinCont->Value(j)->Curve3d();
1851 theCurve->D1( int2d.ParamOnSecond(), P2, vec );
1852 myLinCont->Value(i)->D1( int2d.ParamOnFirst(), P1, vecU, vecV );
1855 Standard_Real Angle = vec.Angle( N );
1856 Angle = Abs( M_PI/2-Angle );
1857 if (Angle > myTolAng/10.) //????????? //if (Abs( scal ) > myTol3d/100)
1858 { // Pas compatible ==> on enleve une zone en
1859 // contrainte G0 et G1 correspondant
1860 // a une tolerance 3D de 0.01
1862 Standard_Real Tol= 100 * myTol3d;
1866 myLinCont->Value(i)->Curve2dOnSurf()->D1( int2d.ParamOnFirst(), P1, V1);
1867 myLinCont->Value(j)->Curve2dOnSurf()->D1( int2d.ParamOnSecond(), P2, V2);
1868 A1 = V1.Angle( V2 );
1871 if (Abs(Abs(A1) - M_PI) < myTolAng) Tol = 100000 * myTol3d;
1873 if (Affich) cout <<"Angle entre Courbe "<<i<<","<<j
1874 <<" "<<Abs(Abs(A1)-M_PI)<<endl;
1876 if (myLinCont->Value(i)->Order() == 1)
1878 coin = Ci.Resolution(Tol);
1879 coin *= Angle / myTolAng * 10.;
1881 cout<<endl<<"coin = "<<coin<<endl;
1883 Standard_Real Par1 = int2d.ParamOnFirst() - coin;
1884 Standard_Real Par2 = int2d.ParamOnFirst() + coin;
1885 // Stockage de l'intervalle pour la courbe i
1886 PntG1G1->ChangeValue(i).Append( Par1 );
1887 PntG1G1->ChangeValue(i).Append( Par2 );
1891 coin = Cj.Resolution(Tol);
1892 coin *= Angle / myTolAng * 10.;
1894 cout<<endl<<"coin = "<<coin<<endl;
1896 Standard_Real Par1 = int2d.ParamOnSecond() - coin;
1897 Standard_Real Par2 = int2d.ParamOnSecond() + coin;
1898 // Stockage de l'intervalle pour la courbe j
1899 PntG1G1->ChangeValue(j).Append( Par1 );
1900 PntG1G1->ChangeValue(j).Append( Par2 );
1904 } //if (P1.Distance( P2 ) < myTol3d)
1906 //L'intersection 2d correspond a des points 3d eloigne
1907 // On note l'intervalle dans lequel il faudra enlever
1908 // des points pour eviter les doublons ce qui fait une
1909 // erreur dans plate. le point sur la courbe i est enleve
1910 // on conserve celui de la courbe j.
1911 // la longueur de l'intervalle est une longueur 2d
1912 // correspondant a la distance des points en 3d a myTol3d
1913 Standard_Real tolint, Dist;
1914 Dist = P1.Distance(P2);
1915 tolint = Ci.Resolution(Dist);
1916 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() - tolint);
1917 PntInter->ChangeValue(i).Append( int2d.ParamOnFirst() + tolint);
1920 tolint = Cj.Resolution(Dist);
1921 PntInter->ChangeValue(j).
1922 Append( int2d.ParamOnSecond() - tolint);
1923 PntInter->ChangeValue(j).
1924 Append( int2d.ParamOnSecond() + tolint);
1928 cout<<"Attention: Deux points 3d ont la meme projection dist="
1934 Handle(Draw_Marker3D) mark = new (Draw_Marker3D)(P1, Draw_X, Draw_vert);
1936 sprintf(name,"mark_%d",++NbMark);
1937 Draw::Set(name, mark);
1947 //---------------------------------------------------------
1948 // fonction : Discretise
1949 //---------------------------------------------------------
1950 // Discretise les courbes selon le parametre de celle-ci
1951 // le tableau des sequences Parcont contiendera tous les
1952 // parametres des points sur les courbes
1953 // Le champ myPlateCont contiendera les parametre des points envoye a plate
1954 // il excluera les points en double et les zones imcompatibles.
1955 // La premiere partie correspond a la verfication de la compatibilite
1956 // et a la supprssion des points en double.
1957 //---------------------------------------------------------
1958 void GeomPlate_BuildPlateSurface::
1959 Discretise(const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntInter,
1960 const Handle(GeomPlate_HArray1OfSequenceOfReal)& PntG1G1)
1962 Standard_Integer NTLinCont = myLinCont->Length();
1963 Standard_Boolean ACR;
1964 Handle(Geom2d_Curve) C2d;
1965 Geom2dAdaptor_Curve AC2d;
1966 // Handle(Adaptor_HCurve2d) HC2d;
1967 Handle(Law_Interpol) acrlaw = new (Law_Interpol) ();
1968 myPlateCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1969 myParCont = new GeomPlate_HArray1OfSequenceOfReal(1,NTLinCont);
1972 //===========================================================================
1973 // Construction du tableau contenant les parametres des points de contrainte
1974 //===========================================================================
1975 Standard_Real Uinit, Ufinal, Length2d=0, Inter;
1976 Standard_Real CurLength;
1977 Standard_Integer NbPnt_i, NbPtInter, NbPtG1G1;
1978 Handle(GeomPlate_CurveConstraint) LinCont;
1980 for (Standard_Integer i=1;i<=NTLinCont;i++) {
1981 LinCont = myLinCont->Value(i);
1982 Uinit=LinCont->FirstParameter();
1983 Ufinal=LinCont->LastParameter();
1984 // HC2d=LinCont->ProjectedCurve();
1985 // if(HC2d.IsNull())
1986 // ACR = (!HC2d.IsNull() || !C2d.IsNull());
1987 C2d= LinCont->Curve2dOnSurf();
1988 ACR = (!C2d.IsNull());
1990 // On Construit une loi proche de l'abscisse curviligne
1991 if(!C2d.IsNull()) AC2d.Load(C2d);
1992 // AC2d.Load(LinCont->Curve2dOnSurf());
1993 Standard_Integer ii, Nbint = 20;
1995 TColgp_Array1OfPnt2d tabP2d(1, Nbint+1);
1996 tabP2d(1).SetY(Uinit);
1998 tabP2d(Nbint+1).SetY(Ufinal);
1999 /* if (!HC2d.IsNull())
2001 Length2d = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, Ufinal);
2003 Length2d = GCPnts_AbscissaPoint::Length(AC2d, Uinit, Ufinal);
2005 tabP2d(Nbint+1).SetX(Length2d);
2006 for (ii = 2; ii<= Nbint; ii++) {
2007 U = Uinit + (Ufinal-Uinit)*((1-Cos((ii-1)*M_PI/(Nbint)))/2);
2009 /* if (!HC2d.IsNull()) {
2010 Standard_Real L = GCPnts_AbscissaPoint::Length(HC2d->Curve2d(), Uinit, U);
2014 tabP2d(ii).SetX(GCPnts_AbscissaPoint::Length(AC2d, Uinit, U));
2016 acrlaw->Set(tabP2d);
2019 NbPnt_i = (Standard_Integer )( LinCont->NbPoints());
2020 NbPtInter= PntInter->Value(i).Length();
2021 NbPtG1G1= PntG1G1->Value(i).Length();
2025 cout << "Courbe : " << i << endl;
2026 cout << " NbPnt, NbPtInter, NbPtG1G1 :" << NbPnt_i << ", "
2027 << NbPtInter << ", " << NbPtG1G1 << endl;
2030 for (Standard_Integer j=1; j<=NbPnt_i; j++)
2032 // repartition des points en cosinus selon l'ACR 2d
2033 // Afin d'eviter les points d'acumulation dans le 2d
2034 //Inter=Uinit+(Uif)*((-cos(M_PI*((j-1)/(NbPnt_i-1)))+1)/2);
2036 Inter=Ufinal;//pour parer au bug sur sun
2038 CurLength = Length2d*(1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2;
2039 Inter = acrlaw->Value(CurLength);
2042 Inter=Uinit+(Ufinal-Uinit)*((1-Cos((j-1)*M_PI/(NbPnt_i-1)))/2);
2044 myParCont->ChangeValue(i).Append(Inter);// on ajoute le point
2047 for(Standard_Integer l=1;l<=NbPtInter;l+=2)
2049 //on cherche si le point Inter est dans l'intervalle
2050 //PntInter[i] PntInter[i+1]
2051 //auquelle cas il ne faudrait pas le stocker (pb de doublons)
2052 if ((Inter>PntInter->Value(i).Value(l))
2053 &&(Inter<PntInter->Value(i).Value(l+1)))
2056 // pour sortir de la boucle sans stocker le point
2060 if (l+1>=NbPtInter) {
2061 // on a parcouru tout le tableau : Le point
2062 // n'appartient pas a un interval point commun
2065 // est qu'il existe un intervalle incompatible
2066 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2068 if ((Inter>PntG1G1->Value(i).Value(k))
2069 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2071 k=NbPtG1G1+2; // pour sortir de la boucle
2072 // Ajouter les points de contrainte G0
2076 AC2d.D0(Inter, P2d);
2077 LinCont->D0(Inter,P3d);
2078 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2079 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2080 -PP.Coord(2)+P3d.Coord(2),
2081 -PP.Coord(3)+P3d.Coord(3));
2082 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2085 else // le point n'appartient pas a un interval G1
2089 myPlateCont->ChangeValue(i).Append(Inter);
2090 // on ajoute le point
2097 myPlateCont->ChangeValue(i).Append(Inter);
2098 // on ajoute le point
2106 if (NbPtG1G1!=0) // est qu'il existe un intervalle incompatible
2108 for(Standard_Integer k=1;k<=NbPtG1G1;k+=2)
2110 if ((Inter>PntG1G1->Value(i).Value(k))
2111 &&(Inter<PntG1G1->Value(i).Value(k+1)))
2113 k=NbPtG1G1+2; // pour sortir de la boucle
2114 // Ajouter les points de contrainte G0
2118 AC2d.D0(Inter, P2d);
2119 LinCont->D0(Inter,P3d);
2120 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2121 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2122 -PP.Coord(2)+P3d.Coord(2),
2123 -PP.Coord(3)+P3d.Coord(3));
2124 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2128 else // le point n'appartient pas a un intervalle G1
2132 myPlateCont->ChangeValue(i).Append(Inter);
2133 // on ajoute le point
2140 if ( ( (!mySurfInitIsGive)
2141 &&(Geom2dAdaptor_Curve(LinCont->Curve2dOnSurf()).GetType()!=GeomAbs_Circle))
2142 || ( (j>1) &&(j<NbPnt_i))) //on enleve les extremites
2143 myPlateCont->ChangeValue(i).Append(Inter);// on ajoute le point
2149 //---------------------------------------------------------
2150 // fonction : CalculNbPtsInit
2151 //---------------------------------------------------------
2152 // Calcul du nombre de points par courbe en fonction de la longueur
2153 // pour la premiere iteration
2154 //---------------------------------------------------------
2155 void GeomPlate_BuildPlateSurface::CalculNbPtsInit ()
2157 Standard_Real LenT=0;
2158 Standard_Integer NTLinCont=myLinCont->Length();
2159 Standard_Integer NTPoint=(Standard_Integer )( myNbPtsOnCur*NTLinCont);
2160 Standard_Integer i ;
2162 for ( i=1;i<=NTLinCont;i++)
2163 LenT+=myLinCont->Value(i)->Length();
2164 for ( i=1;i<=NTLinCont;i++)
2165 { Standard_Integer Cont=myLinCont->Value(i)->Order();
2167 { case 0 : // Cas G0 *1.2
2168 myLinCont->ChangeValue(i)->SetNbPoints(
2169 Standard_Integer(1.2*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2171 case 1 : // Cas G1 *1
2172 myLinCont->ChangeValue(i)->SetNbPoints(
2173 Standard_Integer(NTPoint*(myLinCont->Value(i)->Length())/LenT));
2175 case 2 : // Cas G2 *0.7
2176 myLinCont->ChangeValue(i)->SetNbPoints(
2177 Standard_Integer(0.7*NTPoint*(myLinCont->Value(i)->Length())/LenT));
2180 if (myLinCont->Value(i)->NbPoints()<3)
2181 myLinCont->ChangeValue(i)->SetNbPoints(3);
2184 //---------------------------------------------------------
2185 // fonction : LoadCurve
2186 //---------------------------------------------------------
2187 // A partir du tableau myParCont on charge tous les points notes dans plate
2188 //---------------------------------------------------------
2189 void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle,
2190 const Standard_Integer OrderMax )
2194 Standard_Integer NTLinCont=myLinCont->Length(), i, j;
2195 Standard_Integer Tang, Nt;
2198 for (i=1; i<=NTLinCont; i++){
2199 Handle(GeomPlate_CurveConstraint) CC = myLinCont->Value(i);
2200 if (CC ->Order()!=-1) {
2201 Tang = Min(CC->Order(), OrderMax);
2202 Nt = myPlateCont->Value(i).Length();
2204 for (j=1; j<=Nt; j++) {// Chargement des points G0 sur les frontieres
2205 CC ->D0(myPlateCont->Value(i).Value(j),P3d);
2206 if (!CC->ProjectedCurve().IsNull())
2207 P2d = CC->ProjectedCurve()->Value(myPlateCont->Value(i).Value(j));
2210 if (!CC->Curve2dOnSurf().IsNull())
2211 P2d = CC->Curve2dOnSurf()->Value(myPlateCont->Value(i).Value(j));
2213 P2d = ProjectPoint(P3d);
2215 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2216 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2217 -PP.Coord(2)+P3d.Coord(2),
2218 -PP.Coord(3)+P3d.Coord(3));
2219 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2222 // Chargement des points G1
2223 if (Tang==1) { // ==1
2225 CC->D1( myPlateCont->Value(i).Value(j), PP, V1, V2 );
2226 mySurfInit->D1( P2d.Coord(1), P2d.Coord(2), PP, V3, V4 );
2228 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2229 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2232 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2235 else if (NbBoucle == 1)
2237 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2238 myPlate.Load( FreeGCC );
2241 gp_Vec DU, DV, Normal, DerPlateU, DerPlateV;
2244 //Normal.Normalize();
2245 Standard_Real norm = Normal.Magnitude();
2246 if (norm > 1.e-12) Normal /= norm;
2247 DerPlateU = myPrevPlate.EvaluateDerivative( P2d.XY(), 1, 0 );
2248 DerPlateV = myPrevPlate.EvaluateDerivative( P2d.XY(), 0, 1 );
2250 DU.SetLinearForm(-(V3 + DerPlateU).Dot(Normal), Normal, DerPlateU);
2251 DV.SetLinearForm(-(V4 + DerPlateV).Dot(Normal), Normal, DerPlateV);
2252 Plate_PinpointConstraint PinU( P2d.XY(), DU.XYZ(), 1, 0 );
2253 Plate_PinpointConstraint PinV( P2d.XY(), DV.XYZ(), 0, 1 );
2254 myPlate.Load( PinU );
2255 myPlate.Load( PinV );
2258 // Chargement des points G2
2260 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2261 CC->D2(myPlateCont->Value(i).Value(j),
2263 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2265 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2266 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2267 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2268 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2271 Plate_GtoCConstraint GCC(P2d.XY(),D1init,D1final,D2init,D2final);
2274 // else // Good but too expansive
2276 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(),
2277 // D1init, D1final, D2init, D2final );
2278 // myPlate.Load( FreeGCC );
2288 //---------------------------------------------------------
2289 //fonction : LoadPoint
2290 //---------------------------------------------------------
2291 //void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer NbBoucle,
2292 void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer ,
2293 const Standard_Integer OrderMax)
2297 Standard_Integer NTPntCont=myPntCont->Length();
2298 Standard_Integer Tang, i;
2299 // gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2302 // Chargement des points de contraintes ponctuel
2303 for (i=1;i<=NTPntCont;i++) {
2304 myPntCont->Value(i)->D0(P3d);
2305 P2d = myPntCont->Value(i)->Pnt2dOnSurf();
2306 mySurfInit->D0(P2d.Coord(1),P2d.Coord(2),PP);
2307 Pdif.SetCoord(-PP.Coord(1)+P3d.Coord(1),
2308 -PP.Coord(2)+P3d.Coord(2),
2309 -PP.Coord(3)+P3d.Coord(3));
2310 Plate_PinpointConstraint PC(P2d.XY(),Pdif.XYZ(),0,0);
2312 Tang = Min(myPntCont->Value(i)->Order(), OrderMax);
2313 if (Tang==1) {// ==1
2314 myPntCont->Value(i)->D1(PP,V1,V2);
2315 mySurfInit->D1(P2d.Coord(1),P2d.Coord(2),PP,V3,V4);
2316 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2317 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2320 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final );
2321 myPlate.Load( GCC );
2325 Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final );
2326 myPlate.Load( FreeGCC );
2329 // Chargement des points G2 GeomPlate_PlateG0Criterion
2331 { gp_Vec V1,V2,V3,V4,V5,V6,V7,V8,V9,V10;
2332 myPntCont->Value(i)->D2(PP,V1,V2,V5,V6,V7);
2333 // gp_Vec Tv2 = V1^V2;
2334 mySurfInit->D2(P2d.Coord(1),P2d.Coord(2),PP,V3,V4,V8,V9,V10);
2335 Plate_D1 D1final(V1.XYZ(),V2.XYZ());
2336 Plate_D1 D1init(V3.XYZ(),V4.XYZ());
2337 Plate_D2 D2final (V5.XYZ(),V6.XYZ(),V7.XYZ());
2338 Plate_D2 D2init (V8.XYZ(),V9.XYZ(),V10.XYZ());
2341 Plate_GtoCConstraint GCC( P2d.XY(), D1init, D1final, D2init, D2final );
2342 myPlate.Load( GCC );
2344 // else // Good but too expansive
2346 // Plate_FreeGtoCConstraint FreeGCC( P2d.XY(), D1init, D1final, D2init//, D2final );
2347 // myPlate.Load( FreeGCC );
2353 //---------------------------------------------------------
2354 //fonction : VerifSurface
2355 //---------------------------------------------------------
2356 Standard_Boolean GeomPlate_BuildPlateSurface::
2357 VerifSurface(const Standard_Integer NbBoucle)
2359 //======================================================================
2360 // Calcul des erreurs
2361 //======================================================================
2362 Standard_Integer NTLinCont=myLinCont->Length();
2363 Standard_Boolean Result=Standard_True;
2365 // variable pour les calculs d erreur
2366 myG0Error=0,myG1Error =0, myG2Error=0;
2368 for (Standard_Integer i=1;i<=NTLinCont;i++) {
2369 Handle(GeomPlate_CurveConstraint) LinCont;
2370 LinCont = myLinCont->Value(i);
2371 if (LinCont->Order()!=-1) {
2372 Standard_Integer NbPts_i = myParCont->Value(i).Length();
2375 Handle(TColStd_HArray1OfReal) tdist =
2376 new TColStd_HArray1OfReal(1,NbPts_i-1);
2377 Handle(TColStd_HArray1OfReal) tang =
2378 new TColStd_HArray1OfReal(1,NbPts_i-1);
2379 Handle(TColStd_HArray1OfReal) tcourb =
2380 new TColStd_HArray1OfReal(1,NbPts_i-1);
2382 EcartContraintesMil (i,tdist,tang,tcourb);
2384 Standard_Real diffDistMax=0,SdiffDist=0;
2385 Standard_Real diffAngMax=0,SdiffAng=0;
2386 Standard_Integer NdiffDist=0,NdiffAng=0;
2389 for (Standard_Integer j=1;j<NbPts_i;j++)
2390 { if (tdist->Value(j)>myG0Error)
2391 myG0Error=tdist->Value(j);
2392 if (tang->Value(j)>myG1Error)
2393 myG1Error=tang->Value(j);
2394 if (tcourb->Value(j)>myG2Error)
2395 myG2Error=tcourb->Value(j);
2397 if (myParCont->Value(i).Length()>3)
2398 U=(myParCont->Value(i).Value(j)+myParCont->Value(i).Value(j+1))/2;
2400 U=LinCont->FirstParameter()+
2401 ( LinCont->LastParameter()-LinCont->FirstParameter())*(j-1)/(NbPts_i-2);
2402 Standard_Real diffDist=tdist->Value(j)-LinCont->G0Criterion(U),diffAng;
2403 if (LinCont->Order()>0)
2404 diffAng=tang->Value(j)-LinCont->G1Criterion(U);
2406 // recherche de la variation de l'erreur maxi et calcul de la moyenne
2408 diffDist = diffDist/LinCont->G0Criterion(U);
2409 if (diffDist>diffDistMax)
2410 diffDistMax = diffDist;
2411 SdiffDist+=diffDist;
2414 if ((Affich) && (NbBoucle == myNbIter)) {
2418 Handle(Draw_Marker3D) mark =
2419 new (Draw_Marker3D)(P, Draw_X, Draw_orange);
2421 sprintf(name,"mark_%d",++NbMark);
2422 Draw::Set(name, mark);
2423 if (!LinCont->ProjectedCurve().IsNull())
2424 P2d = LinCont->ProjectedCurve()->Value(U);
2426 { if (!LinCont->Curve2dOnSurf().IsNull())
2427 P2d = LinCont->Curve2dOnSurf()->Value(U);
2429 P2d = ProjectPoint(P);
2431 sprintf(name,"mark2d_%d",++NbMark);
2432 Handle(Draw_Marker2D) mark2d =
2433 new (Draw_Marker2D)(P2d, Draw_X, Draw_orange);
2434 Draw::Set(name, mark2d);
2439 if ((diffAng>0)&&(LinCont->Order()==1)) {
2440 diffAng=diffAng/myLinCont->Value(i)->G1Criterion(U);
2441 if (diffAng>diffAngMax)
2442 diffAngMax = diffAng;
2446 if ((Affich) && (NbBoucle == myNbIter)) {
2449 Handle(Draw_Marker3D) mark =
2450 new Draw_Marker3D(P, Draw_X, Draw_or);
2452 sprintf(name,"mark_%d",++NbMark);
2453 Draw::Set(name, mark);
2459 if (NdiffDist>0) {// au moins un point n'est pas acceptable en G0
2461 if(LinCont->Order()== 0)
2462 Coef = 0.6*Log(diffDistMax+7.4);
2463 //7.4 correspond au calcul du coef mini = 1.2 donc e^1.2/0.6
2465 Coef = Log(diffDistMax+3.3);
2466 //3.3 correspond au calcul du coef mini = 1.2 donc e^1.2
2469 //experimentalement apres le coef devient mauvais pour les cas L
2470 if ((NbBoucle>1)&&(diffDistMax>2))
2474 if (LinCont->NbPoints()>=Floor(LinCont->NbPoints()*Coef))
2475 Coef=2;// pour assurer une augmentation du nombre de points
2477 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints() * Coef));
2478 Result=Standard_False;
2481 if (NdiffAng>0) // au moins 1 points ne sont pas accepable en G1
2482 { Standard_Real Coef=1.5;
2483 if ((LinCont->NbPoints()+1)>=Floor(LinCont->NbPoints()*Coef))
2486 LinCont->SetNbPoints(Standard_Integer(LinCont->NbPoints()*Coef )) ;
2487 Result=Standard_False;
2493 if (myFree && NbBoucle == 1)
2494 myPrevPlate = myPlate;
2502 //---------------------------------------------------------
2503 //fonction : VerifPoint
2504 //---------------------------------------------------------
2505 void GeomPlate_BuildPlateSurface::
2506 VerifPoints (Standard_Real& Dist,
2508 Standard_Real& Curv) const
2509 { Standard_Integer NTPntCont=myPntCont->Length();
2512 gp_Vec v1i, v1f, v2i, v2f, v3i, v3f;
2513 Ang=0;Dist=0,Curv=0;
2514 Handle(GeomPlate_PointConstraint) PntCont;
2515 for (Standard_Integer i=1;i<=NTPntCont;i++) {
2516 PntCont = myPntCont->Value(i);
2517 switch (PntCont->Order())
2519 P2d = PntCont->Pnt2dOnSurf();
2521 myGeomPlateSurface->D0( P2d.Coord(1), P2d.Coord(2), Pf);
2522 Dist = Pf.Distance(Pi);
2525 PntCont->D1(Pi, v1i, v2i);
2526 P2d = PntCont->Pnt2dOnSurf();
2527 myGeomPlateSurface->D1( P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f);
2528 Dist = Pf.Distance(Pi);
2529 v3i = v1i^v2i; v3f=v1f^v2f;
2535 Handle(Geom_Surface) Splate;
2536 Splate = Handle(Geom_Surface)::DownCast(myGeomPlateSurface);
2537 LocalAnalysis_SurfaceContinuity CG2;
2538 P2d = PntCont->Pnt2dOnSurf();
2539 GeomLProp_SLProps Prop (Splate, P2d.Coord(1), P2d.Coord(2),
2541 CG2.ComputeAnalysis(Prop, PntCont->LPropSurf(),GeomAbs_G2);
2544 Curv=CG2.G2CurvatureGap();
2550 Standard_Real GeomPlate_BuildPlateSurface::ComputeAnisotropie() const
2560 Standard_Boolean GeomPlate_BuildPlateSurface::IsOrderG1() const
2562 Standard_Boolean result = Standard_True;
2563 for (Standard_Integer i = 1; i <= myLinCont->Length(); i++)
2564 if (myLinCont->Value(i)->Order() < 1)
2566 result = Standard_False;