c8c67eb8295afdc460ff25f1296f10fe9f748e77
[occt.git] / src / TPrsStd / TPrsStd_ConstraintTools.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 // Language:    C++
19 // Version:     Euclid Designer 2.0
20 // Purpose:     Update AIS object from a TDataXtd_Constraint.
21 // Modified     Mon 30 10:15:43 1998 by SZY
22
23
24 #include <TPrsStd_ConstraintTools.ixx>
25
26 #include <stdio.h>
27 #include <UnitsAPI.hxx>
28 #include <TCollection_ExtendedString.hxx>
29
30 #include <TNaming_Tool.hxx>
31 #include <TNaming_Iterator.hxx>
32 #include <TNaming_NamedShape.hxx>
33 #include <TDF_Label.hxx>
34 #include <TDataStd_Real.hxx>
35 #include <TDataStd_Name.hxx>
36 #include <TDataXtd_Geometry.hxx>
37 #include <TDF_Reference.hxx>
38
39
40 #include <AIS_OffsetDimension.hxx>
41 #include <AIS_LengthDimension.hxx>
42 #include <AIS_ParallelRelation.hxx>
43 #include <AIS_TangentRelation.hxx>
44 #include <AIS_IdenticRelation.hxx>
45 #include <AIS_AngleDimension.hxx>
46 #include <AIS_RadiusDimension.hxx>
47 #include <AIS_DiameterDimension.hxx>
48 #include <AIS_FixRelation.hxx>
49 #include <AIS_PerpendicularRelation.hxx>
50 #include <AIS_ConcentricRelation.hxx>
51 #include <AIS_SymmetricRelation.hxx>
52 #include <AIS_MidPointRelation.hxx>
53 #include <AIS_InteractiveContext.hxx>
54 #include <AIS_Drawer.hxx>
55 #include <AIS_EqualRadiusRelation.hxx>
56 #include <AIS_EqualDistanceRelation.hxx>
57 #include <AIS_MinRadiusDimension.hxx> 
58 #include <AIS_MaxRadiusDimension.hxx>
59
60 #include <TopoDS.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Shape.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopExp.hxx>
66 #include <TopExp_Explorer.hxx>
67
68 #include <BRep_Tool.hxx>
69 #include <BRep_Builder.hxx>
70 #include <BRepBuilderAPI_MakeFace.hxx>
71 #include <BRepAdaptor_Curve.hxx>
72 #include <BRepAdaptor_Surface.hxx>
73
74 #include <GeomAbs_SurfaceType.hxx>
75 #include <Geom_Geometry.hxx>
76 #include <Geom_Line.hxx>
77 #include <Geom_Plane.hxx>
78 #include <Geom_CartesianPoint.hxx>
79 #include <Geom_Circle.hxx>
80 #include <gp_Pln.hxx>
81 #include <gp_Dir.hxx>
82 #include <gp_Ax1.hxx>
83 #include <gp_Lin.hxx>
84 #include <gp_Pnt.hxx>
85 #include <gp_Cylinder.hxx>
86 #include <gp_Cone.hxx>
87 #include <gp_Torus.hxx>
88 #include <GC_MakePlane.hxx> 
89
90 #include <Precision.hxx>
91 #include <IntAna_QuadQuadGeo.hxx>
92
93 #include <Standard_ProgramError.hxx>
94 #include <Standard_ErrorHandler.hxx>
95
96 #include <TopTools_IndexedMapOfShape.hxx>
97
98 #define BUC60846
99
100 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& , const TopoDS_Shape& ); //ota
101
102 //=======================================================================
103 //function : static NullifyAIS
104 //purpose  : 
105 //=======================================================================
106 static void NullifyAIS ( Handle(AIS_InteractiveObject)& anais)
107 {
108   if (anais.IsNull())  return;
109   anais.Nullify();
110 }
111
112
113
114 //=======================================================================
115 //function : static FindExternalShape
116 //purpose  : 
117 //=======================================================================
118 static void FindExternalShape(const Handle(TDataXtd_Constraint)& aConst,
119                               Standard_Integer& extShape)
120 {
121   extShape = 0;
122     const TDF_Label& L =  aConst->Label();
123     if (!aConst->GetGeometry(1)->Label().IsDescendant(L)) extShape = 1;    
124     else if (!aConst->GetGeometry(2)->Label().IsDescendant(L)) extShape = 2;
125 }
126
127 //=======================================================================
128 //function : static GetGoodShape for planar constraint
129 //purpose  : 
130 //=======================================================================
131 static void  GetGoodShape(TopoDS_Shape& shape)
132 {
133   switch (shape.ShapeType()) {
134   case TopAbs_EDGE:
135   case TopAbs_VERTEX: { return; }
136   default:
137     {
138       TopExp_Explorer EXP(shape,TopAbs_EDGE);
139       if (EXP.More()) {
140         shape = EXP.Current();
141         return;
142       }
143       else {
144         EXP.Init(shape,TopAbs_VERTEX);
145         if (EXP.More()) shape = EXP.Current();
146       }
147     }
148   }
149 }
150
151 // Pour le cas ou S est un compound
152 static Standard_Boolean IsFace (const TopoDS_Shape& S)
153 {
154   Standard_Boolean  findface = Standard_False;
155   TopExp_Explorer EXP (S,TopAbs_FACE);
156   if (EXP.More()) findface = Standard_True;
157   return  findface;
158 }
159
160 static TopoDS_Face  GetFace (const TopoDS_Shape& S)
161 {
162   TopoDS_Face F;
163   TopExp_Explorer EXP (S,TopAbs_FACE);
164   if (EXP.More())  F = TopoDS::Face (EXP.Current());
165   return  F;
166 }
167
168 static TopoDS_Edge  GetEdge (const TopoDS_Shape& S)
169 {
170   TopoDS_Edge E;
171   TopExp_Explorer EXP (S, TopAbs_EDGE);
172   if (EXP.More()) E = TopoDS::Edge (EXP.Current());
173   return  E;
174 }
175
176
177
178 //=======================================================================
179 //Function : ComputeAndTextValue
180 //purpose  : 
181 //=======================================================================
182 void TPrsStd_ConstraintTools::ComputeTextAndValue(const Handle(TDataXtd_Constraint)& aConst,
183                                                  Standard_Real&                val,
184                                                  TCollection_ExtendedString&   txt,
185                                                  const Standard_Boolean  anIsAngle  )
186 {
187   Standard_Real outvalue;
188   const Handle(TDataStd_Real)& VAL = aConst->GetValue();
189   val      = VAL->Get();
190   if(anIsAngle){
191     outvalue = UnitsAPI::CurrentFromLS(Abs(val),"PLANE ANGLE");
192   }
193   else {
194     outvalue = UnitsAPI::CurrentFromLS(val,"LENGTH");
195   }
196   char res[1000];
197   sprintf(res,"%g",outvalue);
198   txt = TCollection_ExtendedString(res);
199   
200   if (VAL->IsCaptured()) {
201     Handle(TDF_Reference) ref;
202     VAL->Label().FindAttribute(TDF_Reference::GetID(),ref);
203     Handle(TDataStd_Name) name;
204     const TDF_Label& L = ref->Get();
205     if (ref->Get().FindAttribute(TDataStd_Name::GetID(),name)) {
206       TCollection_ExtendedString fullname;
207       Handle(TDataStd_Name) Fathername;
208       if (L.Father().FindAttribute(TDataStd_Name::GetID(),Fathername)) {
209         fullname = Fathername->Get() + TCollection_ExtendedString(".") + name->Get();
210       }
211       else fullname = name->Get();
212       txt = fullname + TCollection_ExtendedString("=") + txt;
213     }
214   }
215 }
216
217
218 //=======================================================================
219 //function : UpdateOnlyValue
220 //purpose  : 
221 //=======================================================================
222
223 void TPrsStd_ConstraintTools::UpdateOnlyValue(const Handle(TDataXtd_Constraint)& aConst, 
224                                      const Handle(AIS_InteractiveObject)& anAIS)
225 {
226   if (anAIS.IsNull()) return; 
227   if (!aConst->IsDimension()) return; 
228   Standard_Real val;
229   TCollection_ExtendedString txt;
230   TPrsStd_ConstraintTools:: ComputeTextAndValue(aConst,val,txt,aConst->GetType() == TDataXtd_ANGLE);
231   Handle(AIS_Relation) rel = Handle(AIS_Relation)::DownCast(anAIS);
232   if (!rel.IsNull()) rel->SetText(txt); 
233 }
234
235
236 //=======================================================================
237 //function : ComputeDistance
238 //purpose  : Build an AIS_LengtDimension.
239 //=======================================================================
240 void TPrsStd_ConstraintTools::ComputeDistance (const Handle(TDataXtd_Constraint)& aConst,
241                                               Handle(AIS_InteractiveObject)& anAIS) 
242 {
243   Standard_Integer nbgeom = aConst->NbGeometries();
244   if (nbgeom < 2) {
245 #ifdef DEB
246     cout <<  "TPrsStd_ConstraintTools::ComputeDistance: at least 2 geometries are needed" << endl;
247 #endif
248     NullifyAIS(anAIS);
249     return;
250   }
251   TopoDS_Shape shape1,shape2,shape3 ;
252   Handle(Geom_Geometry) ageom3;
253   Standard_Boolean is_planar(aConst->IsPlanar()),is_directed(Standard_False);
254   AIS_TypeOfDist typedist = AIS_TOD_Unknown;
255
256   // Get shapes and geometry
257   if (is_planar) {
258     if (nbgeom == 2)
259       GetShapesAndGeom (aConst,shape1,shape2,ageom3);
260     else
261       GetShapesAndGeom (aConst,shape1,shape2,shape3,ageom3);
262   }
263   else
264     GetTwoShapes (aConst,shape1,shape2);    
265
266   if (shape1.IsNull() || shape2.IsNull()) {
267 #ifdef DEB
268     cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << endl;
269 #endif
270     NullifyAIS(anAIS);
271     return;
272   }
273
274   Handle(Geom_Plane) aplane;
275   if (is_planar) {
276     if (nbgeom != 2) {
277       is_directed = !shape3.IsNull();
278       if (!is_directed)  {
279 #ifdef DEB
280         cout << "TPrsStd_ConstraintTools::ComputeDistance : null shape" << endl;
281 #endif
282         NullifyAIS(anAIS);
283         return;
284       }
285     }
286
287     GetGoodShape (shape1);
288     GetGoodShape (shape2);
289
290     aplane = Handle(Geom_Plane)::DownCast(ageom3);
291     if (aplane.IsNull()) {
292 #ifdef DEB
293       cout << "TPrsStd_ConstraintTools::ComputeDistance : null plane" << endl;
294 #endif
295       NullifyAIS(anAIS);
296       return;
297     }
298     
299     if (is_directed) {
300       GetGoodShape(shape3);
301       const TopoDS_Edge& E = TopoDS::Edge(shape3);
302       BRepAdaptor_Curve CURVE(E);
303       Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
304       gp_Dir Dir = ((Handle(Geom_Line)&) aGeomGeometry)->Lin().Direction();
305       gp_Dir xdir(aplane->Pln().Position().XDirection());
306       if (Dir.IsParallel(xdir,Precision::Confusion()))
307         typedist = AIS_TOD_Horizontal;
308       else
309         typedist = AIS_TOD_Vertical;
310     }
311   }
312
313   Standard_Real val1;
314   TCollection_ExtendedString txt;
315   ComputeTextAndValue(aConst,val1,txt,Standard_False);
316   
317   //  Arguments de l'AIS
318   Standard_Boolean isface = IsFace(shape1) && IsFace(shape2);
319   Standard_Boolean isedgeface = (shape1.ShapeType () == TopAbs_FACE && 
320                                  shape2.ShapeType () == TopAbs_EDGE);
321   Standard_Boolean is2vertices =(shape1.ShapeType () == TopAbs_VERTEX &&                 //addition 1
322                                  shape2.ShapeType () == TopAbs_VERTEX);
323   if (!isface && !is_planar && !is2vertices)  {
324     // Recherche arguments pouvant convenir
325     if (shape1.ShapeType() == shape2.ShapeType())  {
326       TopoDS_Vertex  v1,v2,v3,v4;
327       if (shape1.ShapeType() == TopAbs_EDGE)  {
328         TopExp::Vertices (TopoDS::Edge(shape1),v1,v2);
329         TopExp::Vertices (TopoDS::Edge(shape2),v3,v4);
330       }
331       else
332       if (shape1.ShapeType() == TopAbs_WIRE)  {
333         TopExp::Vertices (TopoDS::Wire(shape1),v1,v2);
334         TopExp::Vertices (TopoDS::Wire(shape2),v3,v4);
335       }
336       shape1 = v1;
337       gp_Pnt P1 = BRep_Tool::Pnt(v1);
338       gp_Pnt P2 = BRep_Tool::Pnt(v3), P3 = BRep_Tool::Pnt(v4);
339       if (P1.Distance(P2) < P1.Distance(P3))  {
340         shape2 = v3;
341         gp_Ax2 ax2 (P1, gp_Dir (P2.XYZ() - P1.XYZ()));
342         aplane = new Geom_Plane (P1,ax2.XDirection());
343       }
344       else {
345         shape2 = v4;
346         gp_Ax2 ax2 (P1, gp_Dir (P3.XYZ() - P1.XYZ()));
347         aplane = new Geom_Plane (P1,ax2.XDirection());
348       }
349     }
350     else  {
351       if (!isedgeface) {
352         NullifyAIS(anAIS);
353         return;
354       }
355     }
356   }
357
358   //  Update de l'AIS
359   Handle(AIS_LengthDimension) ais;
360   Standard_Boolean SaveDrw = Standard_False;
361   Handle(AIS_Drawer) aDrawer;
362
363   if (!anAIS.IsNull()) {
364     ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
365   }
366
367   if (ais.IsNull())  {
368     if (is2vertices)  {                                        //addition 2
369       gp_Pnt P1 = BRep_Tool::Pnt( TopoDS::Vertex(shape1) );
370       gp_Pnt P2 = BRep_Tool::Pnt( TopoDS::Vertex(shape2) );
371       gp_Pnt P3(P1.Y()-1., P2.X()+1., 0.); 
372       GC_MakePlane mkPlane(P1, P2, P3); 
373       ais = new AIS_LengthDimension (shape1, shape2, mkPlane.Value(), val1,txt);
374     }
375     else if (isface)  {
376       ais = new AIS_LengthDimension (GetFace(shape1),GetFace(shape2),val1,txt);
377     }
378     else if (isedgeface) {
379       ais = new AIS_LengthDimension (GetFace(shape1),GetEdge(shape2),val1,txt);
380     }
381     else  {
382       ais = new AIS_LengthDimension (shape1,shape2,aplane,val1,txt);
383     }
384     if( SaveDrw ) ais->SetAttributes(aDrawer);   
385   }
386   else {
387     if (isface)  {
388       ais->SetFirstShape  (GetFace(shape1));
389       ais->SetSecondShape (GetFace(shape2));
390     }
391     else  {
392       ais->SetFirstShape  (shape1);
393       ais->SetSecondShape (shape2);
394     }
395     if (is2vertices)  {                     //addition 3
396       gp_Pnt P1 = BRep_Tool::Pnt( TopoDS::Vertex(shape1) );
397       gp_Pnt P2 = BRep_Tool::Pnt( TopoDS::Vertex(shape2) );
398       gp_Pnt P3(P1.Y()-1., P2.X()+1., 0.); 
399       GC_MakePlane mkPlane(P1, P2, P3); 
400       ais->SetPlane( mkPlane.Value() );
401     }
402
403     ais->SetValue       (val1);
404     ais->SetText        (txt);
405   }
406   
407   if (is_planar) {
408     Standard_Integer extShape (0);
409 #ifndef BUC60846
410     FindExternalShape (aConst,extShape);
411 #endif
412     ais->SetPlane      (aplane);
413     ais->SetTypeOfDist (typedist);
414     ais->SetExtShape   (extShape);
415   }
416   anAIS = ais;
417 }
418
419 //=======================================================================
420 //function : ComputePerpendicular
421 //purpose  : 
422 //=======================================================================
423 void TPrsStd_ConstraintTools::ComputePerpendicular(const Handle(TDataXtd_Constraint)& aConst,
424                                                   Handle(AIS_InteractiveObject)& anAIS) 
425 {
426   Standard_Integer nbgeom = aConst->NbGeometries();
427   if (nbgeom < 2) {
428 #ifdef DEB
429     cout << "TPrsStd_ConstraintTools::ComputePerpendicular: at leat two constraintes are needed" << endl;
430 #endif
431     NullifyAIS(anAIS);
432     return;
433   }
434   
435   TopoDS_Shape shape1,shape2 ;
436   Handle(Geom_Geometry) ageom3;
437   Standard_Boolean is_planar(aConst->IsPlanar());
438   
439   if (is_planar) GetShapesAndGeom(aConst,shape1,shape2,ageom3);
440   else GetTwoShapes(aConst,shape1,shape2); 
441   if (shape1.IsNull() || shape2.IsNull()) {
442 #ifdef DEB
443     cout << "TPrsStd_ConstraintTools::ComputePerpendicular : null shape" << endl;
444 #endif
445     NullifyAIS(anAIS);
446     return;
447   }
448   GetGoodShape(shape1);
449   GetGoodShape(shape2);
450   //  Update de l'AIS
451   Handle(AIS_PerpendicularRelation) ais;
452   if (anAIS.IsNull()) ais = new AIS_PerpendicularRelation(shape1,shape2);
453   else {
454     ais = Handle(AIS_PerpendicularRelation)::DownCast(anAIS);
455     if (ais.IsNull()) {
456       ais = new AIS_PerpendicularRelation(shape1,shape2);
457     }
458     else {
459       ais->SetFirstShape(shape1);
460       ais->SetSecondShape(shape2);
461     }
462   }
463   
464   if (is_planar) {
465     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
466     if (aplane.IsNull()) {
467 #ifdef DEB
468       cout << "TPrsStd_ConstraintTools::ComputePerpendicular: nul plane" << endl;
469 #endif
470       NullifyAIS(anAIS);
471       return;
472     }
473     ais->SetPlane(aplane);
474   }
475   anAIS = ais;
476 }
477
478 //=======================================================================
479 //function : ComputeParallel
480 //purpose  : 
481 //=======================================================================
482 void TPrsStd_ConstraintTools::ComputeParallel(const Handle(TDataXtd_Constraint)& aConst, 
483                                              Handle(AIS_InteractiveObject)& anAIS) 
484 {
485   Standard_Integer nbgeom = aConst->NbGeometries();
486   if (nbgeom < 2) {
487 #ifdef DEB
488     cout << "TPrsStd_ConstraintTools::ComputeParallel: at least 2 constraintes are needed" << endl;
489 #endif
490     NullifyAIS(anAIS);
491     return;
492   }
493   
494   if (!aConst->IsPlanar()) {
495 #ifdef DEB
496     cout << "TPrsStd_ConstraintTools::ComputeParallel: must be a planar constraint" << endl;
497 #endif
498     NullifyAIS(anAIS);
499     return;
500   }
501
502   TopoDS_Shape shape1,shape2 ;
503   Handle(Geom_Geometry) ageom3;
504   
505   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
506   if (shape1.IsNull() || shape2.IsNull()) {
507 #ifdef DEB
508     cout << "TPrsStd_ConstraintTools::ComputeParallel : null shape" << endl;
509 #endif
510     NullifyAIS(anAIS);
511     return;
512   }
513   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
514   if (aplane.IsNull()) {
515 #ifdef DEB
516     cout << "TPrsStd_ConstraintTools::ComputeParallel: nul plane" << endl;
517 #endif
518     NullifyAIS(anAIS);
519     return;
520   }
521   //  Update de l'AIS
522   GetGoodShape(shape1);
523   GetGoodShape(shape2);
524   Handle(AIS_ParallelRelation) ais;
525   if (anAIS.IsNull()) ais = new AIS_ParallelRelation(shape1,shape2,aplane);
526   else { 
527     ais = Handle(AIS_ParallelRelation)::DownCast(anAIS);
528     if (ais.IsNull()) {
529       ais = new AIS_ParallelRelation(shape1,shape2,aplane);
530     }
531     else {
532       ais->SetFirstShape(shape1);
533       ais->SetSecondShape(shape2);
534       ais->SetPlane(aplane);
535     }
536   }
537   anAIS = ais;
538 }
539 //=======================================================================
540 //function : ComputeSymmetry
541 //purpose  : 
542 //=======================================================================
543 void TPrsStd_ConstraintTools::ComputeSymmetry(const Handle(TDataXtd_Constraint)& aConst,
544                                              Handle(AIS_InteractiveObject)& anAIS) 
545 {
546   Standard_Integer nbgeom = aConst->NbGeometries();
547   if (nbgeom < 3) {
548 #ifdef DEB
549     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraintes are needed" << endl;
550 #endif
551     NullifyAIS(anAIS);
552     return;
553   }
554
555   Standard_Boolean is_planar(aConst->IsPlanar());
556   if (!is_planar) {
557 #ifdef DEB
558     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << endl;
559 #endif
560     NullifyAIS(anAIS);
561     return;
562   }
563
564   TopoDS_Shape shape1,shape2,shape3 ;
565   Handle(Geom_Geometry) ageom3;
566   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
567
568   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull()) {
569 #ifdef DEB
570     cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << endl;
571 #endif
572     NullifyAIS(anAIS);
573     return;
574   }
575   GetGoodShape(shape1);
576   GetGoodShape(shape2);
577   GetGoodShape(shape3);
578   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
579   if (aplane.IsNull()) {
580 #ifdef DEB
581     cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << endl;
582 #endif
583     NullifyAIS(anAIS);
584     return;
585   }
586   //  Update de l'AIS
587   Handle(AIS_SymmetricRelation) ais;
588   if (anAIS.IsNull()) ais = new AIS_SymmetricRelation(shape3,shape1,shape2,aplane);
589   else {
590     ais = Handle(AIS_SymmetricRelation)::DownCast(anAIS);
591     if (ais.IsNull()) {
592       ais = new AIS_SymmetricRelation(shape3,shape1,shape2,aplane);
593     }
594     else {
595       ais->SetFirstShape(shape1);
596       ais->SetSecondShape(shape2);
597       ais->SetPlane(aplane);
598       ais->SetTool(shape3);
599     }
600   }
601   anAIS = ais;
602 }
603
604 //=======================================================================
605 //function : ComputeMidPoint
606 //purpose  : 
607 //=======================================================================
608 void TPrsStd_ConstraintTools::ComputeMidPoint(const Handle(TDataXtd_Constraint)& aConst,
609                                               Handle(AIS_InteractiveObject)& anAIS) 
610 {
611   Standard_Integer nbgeom = aConst->NbGeometries();
612   if (nbgeom < 3)
613     {
614 #ifdef DEB
615       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: at least 3 constraints are needed" << endl;
616 #endif
617       NullifyAIS(anAIS);
618       return;
619     }
620
621   Standard_Boolean is_planar(aConst->IsPlanar());
622   if ( !is_planar )
623     {
624 #ifdef DEB
625       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: must be a planar constraint" << endl;
626 #endif
627       NullifyAIS(anAIS);
628       return;
629     }
630
631   TopoDS_Shape shape1,shape2,shape3;
632   Handle(Geom_Geometry) ageom3;
633   GetShapesAndGeom(aConst,shape1,shape2,shape3,ageom3);
634
635   if (shape1.IsNull() || shape2.IsNull() || shape3.IsNull())
636     {
637 #ifdef DEB
638       cout << "TPrsStd_ConstraintTools::ComputeSymmetry : null shape" << endl;
639 #endif
640       NullifyAIS(anAIS);
641       return;
642     }
643   GetGoodShape(shape1);
644   GetGoodShape(shape2);
645   GetGoodShape(shape3);
646
647   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
648   if (aplane.IsNull())
649     {
650 #ifdef DEB
651       cout << "TPrsStd_ConstraintTools::ComputeSymmetry: null plane" << endl;
652 #endif
653       NullifyAIS(anAIS);
654       return;
655     }
656
657   //  Update de l'AIS
658   Handle(AIS_MidPointRelation) ais;
659   if ( anAIS.IsNull() ) ais = new AIS_MidPointRelation(shape3,shape1,shape2,aplane);
660   else
661     {
662       ais = Handle(AIS_MidPointRelation)::DownCast(anAIS);
663       if (ais.IsNull())
664         {
665           ais = new AIS_MidPointRelation(shape3,shape1,shape2,aplane);
666         }
667       else
668         {
669           ais->SetFirstShape(shape1);
670           ais->SetSecondShape(shape2);
671           ais->SetPlane(aplane);
672           ais->SetTool(shape3);
673         }
674     }
675   anAIS = ais;
676 }
677
678 //=======================================================================
679 //function : ComputeTangent
680 //purpose  : 
681 //=======================================================================
682 void TPrsStd_ConstraintTools::ComputeTangent (const Handle(TDataXtd_Constraint)& aConst, 
683                                              Handle(AIS_InteractiveObject)& anAIS) 
684 {
685   Standard_Integer nbgeom = aConst->NbGeometries();
686   if (nbgeom < 2) {
687 #ifdef DEB
688     cout << "TPrsStd_ConstraintTools::ComputeTangent: at leat two constraintes are needed" << endl;
689 #endif
690     NullifyAIS(anAIS);
691     return;
692   }
693   if (!aConst->IsPlanar()) {
694 #ifdef DEB
695     cout << "TPrsStd_ConstraintTools::ComputeTangent: must be a planar constraint" << endl;
696 #endif
697     NullifyAIS(anAIS);
698     return;
699   }
700   TopoDS_Shape shape1,shape2 ;
701   Handle(Geom_Geometry) ageom3;
702   
703   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
704   if (shape1.IsNull() || shape2.IsNull()) {
705 #ifdef DEB
706     cout << "TPrsStd_ConstraintTools::ComputeTangent : null shape" << endl;
707 #endif
708     NullifyAIS(anAIS);
709     return;
710   }
711   GetGoodShape(shape1);
712   GetGoodShape(shape2);
713   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
714   if (aplane.IsNull()) {
715 #ifdef DEB
716     cout << "TPrsStd_ConstraintTools::ComputeTangent: nul plane" << endl;
717 #endif
718     NullifyAIS(anAIS);
719     return;    
720   }
721   //  Update de l'AIS
722   Handle(AIS_TangentRelation) ais;
723   if (anAIS.IsNull())
724     {
725       ais = new AIS_TangentRelation(shape1,shape2,aplane);
726       ais->SetArrowSize(10000000); // jfa 9/10/2000
727     }
728   else
729     {
730       ais = Handle(AIS_TangentRelation)::DownCast(anAIS);
731       if (ais.IsNull())
732         {
733           ais = new AIS_TangentRelation(shape1,shape2,aplane);
734           ais->SetArrowSize(10000000); // jfa 9/10/2000
735         }
736       else
737         {
738           ais->SetFirstShape(shape1);
739           ais->SetSecondShape(shape2);
740           ais->SetPlane(aplane);
741           ais->SetArrowSize(10000000); // jfa 9/10/2000
742         }
743     }
744   anAIS = ais;
745 }
746
747 //=======================================================================
748 //function : ComputeAngleForOneFace
749 //purpose  : computes AngleDimension for one-conical-face case
750 //=======================================================================
751 void TPrsStd_ConstraintTools::ComputeAngleForOneFace (const Handle(TDataXtd_Constraint)& aConst,
752                                            Handle(AIS_InteractiveObject)& anAIS) 
753 {
754  
755   TopoDS_Shape shape;
756   Handle(Geom_Geometry) ageom3;
757   
758   GetOneShape( aConst, shape ); 
759   if (shape.IsNull() ) {
760 #ifdef DEB
761     cout << "TPrsStd_ConstraintTools::ComputeAngleForOneFace : null shape" << endl;
762 #endif
763     NullifyAIS(anAIS);
764     return;
765   }
766
767   Standard_Real val1;
768   TCollection_ExtendedString txt;
769   TPrsStd_ConstraintTools::ComputeTextAndValue (aConst,val1,txt,Standard_True);  
770   
771   Handle(AIS_AngleDimension) ais;
772   TopoDS_Face face;
773   if (!anAIS.IsNull()) {
774     ais = Handle(AIS_AngleDimension)::DownCast(anAIS);
775     if(ais.IsNull()) {
776       face = TopoDS::Face( shape );
777       ais =  new AIS_AngleDimension ( face, val1, txt);
778     }
779     else {
780       ais->SetConeFace(TopoDS::Face( shape ));
781       ais->SetValue(val1);
782       ais->SetText(txt);
783     }
784   }
785   else {
786     face = TopoDS::Face( shape );
787     ais =  new AIS_AngleDimension ( face, val1, txt);
788   } 
789
790   anAIS = ais;
791 }
792
793 //====================================================================
794 static Standard_Boolean CheckIsShapeCompound(TopoDS_Shape& shape, TopoDS_Face& aFace)
795 {
796   if (shape.ShapeType() == TopAbs_COMPOUND) {
797     TopTools_IndexedMapOfShape aFaceMap;
798     TopExp::MapShapes(shape, TopAbs_FACE, aFaceMap);
799     for(Standard_Integer i = 1;i <= aFaceMap.Extent();i++) 
800       {
801         aFace = TopoDS::Face(aFaceMap.FindKey(i));
802         if(!aFace.IsNull()) {
803           shape = aFace;
804           return (Standard_True);
805         }
806       }
807   }
808 #ifdef DEB
809   cout << "TPrsStd::Compute angle : Shape is not Compound or is Null" <<endl;
810 #endif
811   return (Standard_False);
812 }
813 //=======================================================================
814 //function : ComputeAngle
815 //purpose  : 
816 //=======================================================================
817 void TPrsStd_ConstraintTools::ComputeAngle (const Handle(TDataXtd_Constraint)& aConst,
818                                            Handle(AIS_InteractiveObject)& anAIS) 
819 {
820   Standard_Integer nbgeom = aConst->NbGeometries();
821   if (nbgeom < 2) {
822     if( nbgeom == 1 ) { ComputeAngleForOneFace( aConst, anAIS ); return; }
823 #ifdef DEB
824     cout << "TPrsStd_ConstraintTools::ComputeAngle: at least 2 constraints are needed" << endl;
825 #endif
826     NullifyAIS(anAIS);
827     return;
828   }
829   
830   TopoDS_Shape shape1,shape2 ;
831   Handle(Geom_Geometry) ageom3;
832   
833   GetShapesAndGeom (aConst,shape1,shape2,ageom3);
834   if (shape1.IsNull() || shape2.IsNull()) {
835 #ifdef DEB
836     cout << "TPrsStd_ConstraintTools::ComputeAngle : null shape" << endl;
837 #endif
838     NullifyAIS(anAIS);
839     return;
840   }
841   
842   Standard_Boolean isCurvilinear = Standard_False;
843   if (ageom3.IsNull()) {
844     // on essaie de le calculer
845     
846     TopoDS_Face  aFace;
847     if (shape1.ShapeType() == TopAbs_WIRE)  {
848       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape1),Standard_True);
849       if (MkF.IsDone())  {
850         aFace = MkF.Face();
851         shape1 = aFace;
852       }
853     }
854     else
855       if (shape1.ShapeType() == TopAbs_FACE)
856         aFace    = TopoDS::Face(shape1);
857       else
858         if(!CheckIsShapeCompound(shape1, aFace)) {
859 #ifdef DEB
860         cout << "Compute angle : Geom type = " << shape1.ShapeType()
861           << " non traite"<<endl;
862 #endif
863         NullifyAIS(anAIS);
864         return;      
865       }
866
867     gp_Ax1 anax1aFace1;
868     gp_Pln aPlnaFace1;
869
870     BRepAdaptor_Surface   aSurfaFace (aFace);
871     GeomAbs_SurfaceType aTypeaFace = aSurfaFace.GetType();
872     if (aTypeaFace  == GeomAbs_Plane) {
873       aPlnaFace1 = aSurfaFace.Plane();
874       anax1aFace1 = aPlnaFace1.Axis(); // Normale au plan
875     } else if (aTypeaFace  == GeomAbs_Cylinder) {
876       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
877       anax1aFace1 = aCylaFace.Axis();
878     } else if (aTypeaFace  == GeomAbs_Cone) {
879       gp_Cone aCone = aSurfaFace.Cone();
880       anax1aFace1 = aCone.Axis();  
881     } else if (aTypeaFace  == GeomAbs_Torus) {
882       gp_Torus aTore = aSurfaFace.Torus();
883       anax1aFace1 = aTore.Axis();  
884     } else {
885 #ifdef DEB
886       cout<<"Compute angle"<<aTypeaFace<<" non traite"<<endl;
887 #endif
888       NullifyAIS(anAIS);
889       return;      
890     }
891
892     gp_Ax1 anax1aFace2;
893     gp_Pln aPlnaFace2;
894     if (shape2.ShapeType() == TopAbs_WIRE)  {
895       BRepBuilderAPI_MakeFace MkF (TopoDS::Wire(shape2),Standard_True);
896       if (MkF.IsDone())  {
897         aFace = MkF.Face();
898         shape2 = aFace;
899       }
900     }
901     else
902       if (shape2.ShapeType() == TopAbs_FACE)
903         aFace    = TopoDS::Face(shape2); 
904     else  
905       if(!CheckIsShapeCompound(shape2, aFace)) {
906 #ifdef DEB
907         cout << "Compute angle : Geom type = " << shape2.ShapeType()
908           << " non traite"<<endl;
909 #endif
910         NullifyAIS(anAIS);
911         return;      
912       }
913     
914     aSurfaFace.Initialize(aFace);
915     aTypeaFace = aSurfaFace.GetType();
916     if (aTypeaFace  == GeomAbs_Plane) {
917       aPlnaFace2 = aSurfaFace.Plane();
918       anax1aFace2 = aPlnaFace2.Axis(); // Normale au plan
919     } else if (aTypeaFace  == GeomAbs_Cylinder) {
920       gp_Cylinder aCylaFace = aSurfaFace.Cylinder();
921       anax1aFace2 = aCylaFace.Axis();
922     } else if (aTypeaFace  == GeomAbs_Cone) {
923       gp_Cone aCone = aSurfaFace.Cone();
924       anax1aFace2 = aCone.Axis();  
925     } else if (aTypeaFace  == GeomAbs_Torus) {
926       gp_Torus aTore = aSurfaFace.Torus();
927       anax1aFace2 = aTore.Axis();  
928     } else {
929 #ifdef DEB
930       cout << "Compute angle " << aTypeaFace << " non traite"<<endl;
931 #endif
932       NullifyAIS(anAIS);
933       return;      
934     }
935
936     if (aTypeaFace==GeomAbs_Plane) {
937       if (!anax1aFace1.IsParallel(anax1aFace2, Precision::Angular())) {
938         
939         IntAna_QuadQuadGeo IntersectPlane (aPlnaFace1, aPlnaFace2, Precision::Angular(), Precision::Angular());
940         if (IntersectPlane.IsDone() &&
941             (IntersectPlane.TypeInter() != IntAna_Empty))  {
942           gp_Lin aLine = IntersectPlane.Line(1);
943           Handle(Geom_Line) computedgeom3 = new Geom_Line (aLine);
944           ageom3 = computedgeom3;
945         } else {
946 #ifdef DEB
947           cout<<"Compute angle insertection of planes failed"<<endl;
948 #endif
949           NullifyAIS(anAIS);
950           return;            
951         }
952       } else {
953         
954 #ifdef DEB
955         cout<<"Compute angle faces are //"<<endl;
956 #endif
957         NullifyAIS(anAIS);
958         return;            
959       }
960     } else {
961       // Curvilinear faces...
962       isCurvilinear = Standard_True;
963     }
964   } // endif (ageom3.IsNull())
965
966
967   Standard_Boolean isplan(Standard_False);
968
969   if (!isCurvilinear) {
970     if (ageom3->IsKind(STANDARD_TYPE(Geom_Plane))) isplan = Standard_True;
971     else if (ageom3->IsKind(STANDARD_TYPE(Geom_Line))) isplan = Standard_False;
972     else {
973 #ifdef DEB
974       cout << "TPrsStd_ConstraintTools::ComputeAngle: unknown 3rd arg " << endl;
975 #endif
976       NullifyAIS(anAIS);
977       return;
978     }
979   }
980   Standard_Real val1;
981   TCollection_ExtendedString txt;
982   ComputeTextAndValue (aConst,val1,txt,Standard_True);  
983   
984   Standard_Boolean toCreate (Standard_True);
985   Standard_Boolean isface(shape1.ShapeType()==TopAbs_FACE);
986   
987   Handle(AIS_AngleDimension) ais;
988   if (!anAIS.IsNull()) {
989     ais = Handle(AIS_AngleDimension)::DownCast(anAIS);
990     if( ais.IsNull() ) {
991       toCreate = Standard_True;
992     }
993     else toCreate = Standard_False;
994   }
995   
996   Standard_Integer ExtShape(0);
997   if (toCreate)  {
998     // Creation de l'AIS
999     if (isplan) {
1000       if(!isface) {
1001         FindExternalShape(aConst,ExtShape);
1002         GetGoodShape(shape1);
1003         GetGoodShape(shape2);
1004         ais = new AIS_AngleDimension (TopoDS::Edge(shape1),
1005                                       TopoDS::Edge(shape2),
1006                                       (Handle(Geom_Plane)&) ageom3,val1,txt);
1007         ais->SetExtShape(ExtShape);
1008       }
1009     }
1010     else { 
1011       if (isCurvilinear) {
1012         ais = new AIS_AngleDimension (TopoDS::Face(shape1),
1013                                       TopoDS::Face(shape2),val1,txt);
1014       }
1015       else if (isface) {
1016         ais =  new AIS_AngleDimension (TopoDS::Face(shape1),
1017                                        TopoDS::Face(shape2),
1018                                        ((Handle(Geom_Line)&) ageom3)->Position(),val1,txt);
1019       }
1020     }
1021   }
1022   else {
1023     // Update de l'AIS
1024     if (isplan) {
1025       GetGoodShape(shape1);
1026       GetGoodShape(shape2);
1027     }
1028     ais->SetFirstShape(shape1);
1029     ais->SetSecondShape(shape2);
1030     ais->SetValue(val1);
1031     ais->SetText(txt);
1032     if (isplan)
1033       ais->SetPlane ((Handle(Geom_Plane)&) ageom3);
1034     else if (!isCurvilinear)
1035       ais->SetAxis (((Handle(Geom_Line)&) ageom3)->Position());
1036   }
1037   anAIS = ais;
1038 }
1039
1040
1041 //=======================================================================
1042 //function : ComputeConcentric
1043 //purpose  : 
1044 //=======================================================================
1045 void TPrsStd_ConstraintTools::ComputeConcentric(const Handle(TDataXtd_Constraint)& aConst,
1046                                                Handle(AIS_InteractiveObject)& anAIS) 
1047 {
1048   Standard_Integer nbgeom = aConst->NbGeometries();
1049   if (nbgeom < 2) {
1050     Standard_ProgramError::Raise ("TPrsStd_ConstraintTools::ComputeConcentric: at least 2 constraintes are needed");
1051   }
1052   if (!aConst->IsPlanar()) {
1053 #ifdef DEB
1054     cout << "TPrsStd_ConstraintTools::ComputeConcentric: must be a planar constraint" << endl;
1055 #endif
1056     NullifyAIS(anAIS);
1057     return;
1058   }
1059   TopoDS_Shape shape1,shape2 ;
1060   Handle(Geom_Geometry) ageom3;
1061   
1062   GetShapesAndGeom(aConst,shape1,shape2,ageom3);
1063   if (shape1.IsNull() || shape2.IsNull()) {
1064 #ifdef DEB
1065     cout << "TPrsStd_ConstraintTools::ComputeConcentric : null shape" << endl;
1066 #endif
1067     NullifyAIS(anAIS);
1068     return;
1069   }
1070
1071   GetGoodShape(shape1);
1072   GetGoodShape(shape2);
1073
1074 //ota : to allow concentric constraint display between vertex and edge
1075   if (shape1.ShapeType() != TopAbs_EDGE && shape2.ShapeType() != TopAbs_EDGE) {
1076 #ifdef DEB
1077     cout << "TPrsStd_ConstraintTools::ComputeConcentric: concentric between two vertexes : NOT DISPLAYED" << endl;;
1078 #endif
1079     NullifyAIS(anAIS);
1080     return;
1081   }
1082
1083   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom3);
1084   if (aplane.IsNull()) {
1085 #ifdef DEB
1086     cout << "TPrsStd_ConstraintTools::ComputeConcentric: nul plane" << endl;;
1087 #endif
1088     NullifyAIS(anAIS);
1089     return;
1090   }
1091   //  Update de l'AIS
1092   Handle(AIS_ConcentricRelation) ais;
1093   if (!anAIS.IsNull()) {
1094     ais = Handle(AIS_ConcentricRelation)::DownCast(anAIS);
1095     if (ais.IsNull()) {
1096       ais = new AIS_ConcentricRelation (shape1,shape2,aplane);
1097     } 
1098     else {
1099       ais->SetFirstShape(shape1);
1100       ais->SetSecondShape(shape2);
1101       ais->SetPlane(aplane);
1102     }
1103   }
1104   else {
1105     ais = new AIS_ConcentricRelation (shape1,shape2,aplane);
1106   }
1107
1108   anAIS = ais;
1109 }
1110
1111 //=======================================================================
1112 //function : ComputeRadius
1113 //purpose  : 
1114 //=======================================================================
1115 void TPrsStd_ConstraintTools::ComputeRadius (const Handle(TDataXtd_Constraint)& aConst,
1116                                             Handle(AIS_InteractiveObject)& anAIS) 
1117 {
1118   Standard_Integer nbgeom = aConst->NbGeometries();
1119   if (nbgeom < 1) {
1120 #ifdef DEB
1121     cout << "TPrsStd_ConstraintTools::ComputeRadius: at least one constrainte is needed" << endl;    
1122 #endif
1123     NullifyAIS(anAIS);
1124     return;
1125   }
1126
1127   TopoDS_Shape shape1 ;
1128   GetOneShape (aConst,shape1);
1129   if (shape1.IsNull()) {
1130 #ifdef DEB
1131     cout << "TPrsStd_ConstraintTools::ComputeRadius: null shape" << endl;
1132 #endif
1133     NullifyAIS(anAIS);
1134     return;
1135   }
1136
1137   // POP on teste si ce n'est pas un compound
1138   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1139       shape1.ShapeType()==TopAbs_COMPSOLID ||
1140       shape1.ShapeType()==TopAbs_SOLID ||
1141       shape1.ShapeType()==TopAbs_SHELL ) {
1142 #ifdef DEB
1143     cout << "TPrsStd_ConstraintTools::ComputeRadius: not good shape" << endl;
1144 #endif
1145     NullifyAIS(anAIS);
1146     return;
1147   }
1148       
1149   if (IsFace(shape1))
1150     shape1 = GetFace(shape1);
1151
1152   Standard_Real val1;
1153   TCollection_ExtendedString txt;
1154   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1155
1156   //  Update de l'AIS
1157   Standard_Boolean isplanar(aConst->IsPlanar());
1158   if (isplanar) GetGoodShape(shape1);
1159
1160   Handle(AIS_RadiusDimension) ais;
1161   if (!anAIS.IsNull()) {
1162     ais = Handle(AIS_RadiusDimension)::DownCast(anAIS);
1163     if (ais.IsNull()) {
1164       ais = new AIS_RadiusDimension (shape1,val1,txt);
1165     }
1166     else {
1167       ais->SetValue(val1);
1168       ais->SetFirstShape(shape1);
1169       ais->SetText(txt);    
1170     }
1171   }
1172   else ais = new AIS_RadiusDimension (shape1,val1,txt);
1173
1174   if (isplanar) {
1175     Handle(Geom_Geometry) ageom2;
1176     GetGeom(aConst,ageom2);
1177     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1178     if (aplane.IsNull()) {
1179 #ifdef DEB
1180       cout << "TPrsStd_ConstraintTools::ComputeRadius: nul plane" << endl;
1181 #endif
1182       NullifyAIS(anAIS);
1183       return;
1184     }
1185     ais->SetPlane(aplane);
1186     ais->SetDrawFromCenter(Standard_False);
1187   }
1188   anAIS = ais;
1189 }
1190 // ota -- begin --
1191 //=======================================================================
1192 //function : ComputeMinRadius
1193 //purpose  : 
1194 //=======================================================================
1195 void TPrsStd_ConstraintTools::ComputeMinRadius (const Handle(TDataXtd_Constraint)& aConst,
1196                                                 Handle(AIS_InteractiveObject)& anAIS) 
1197 {
1198   Standard_Integer nbgeom = aConst->NbGeometries();
1199   if (nbgeom < 1) {
1200 #ifdef DEB
1201     cout << "TPrsStd_ConstraintTools::ComputeMinRadius: at least one constrainte is needed" << endl;    
1202 #endif
1203     NullifyAIS(anAIS);
1204     return;
1205   }
1206
1207   TopoDS_Shape shape1 ;
1208   GetOneShape (aConst,shape1);
1209   if (shape1.IsNull()) {
1210 #ifdef DEB
1211     cout << "TPrsStd_ConstraintTools::ComputeMinradius: null shape" << endl;
1212 #endif
1213     NullifyAIS(anAIS);
1214     return;
1215   }
1216
1217   // POP on teste si ce n'est pas un compound
1218   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1219       shape1.ShapeType()==TopAbs_COMPSOLID ||
1220       shape1.ShapeType()==TopAbs_SOLID ||
1221       shape1.ShapeType()==TopAbs_SHELL ) {
1222 #ifdef DEB
1223     cout << "TPrsStd_ConstraintTools::ComputeMinRadius: not good shape" << endl;
1224 #endif
1225     NullifyAIS(anAIS);
1226     return;
1227   }
1228       
1229   if (IsFace(shape1))
1230     shape1 = GetFace(shape1);
1231
1232   Standard_Real val1;
1233   TCollection_ExtendedString txt;
1234   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1235
1236   //  Update de l'AIS
1237   Standard_Boolean isplanar(aConst->IsPlanar());
1238   if (isplanar) GetGoodShape(shape1);
1239
1240   Handle(AIS_MinRadiusDimension) ais;
1241   if (!anAIS.IsNull()) {
1242     ais = Handle(AIS_MinRadiusDimension)::DownCast(anAIS);
1243     if (ais.IsNull()) {
1244       ais = new AIS_MinRadiusDimension (shape1,val1,txt);
1245     }
1246     else {
1247       ais->SetValue(val1);
1248       ais->SetFirstShape(shape1);
1249       ais->SetText(txt);    
1250     }
1251   }
1252   else ais = new AIS_MinRadiusDimension (shape1,val1,txt);
1253
1254   if (isplanar) {
1255     Handle(Geom_Geometry) ageom2;
1256     GetGeom(aConst,ageom2);
1257     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1258     if (aplane.IsNull()) {
1259 #ifdef DEB
1260       cout << "TPrsStd_ConstraintTools::ComputeMinRadius: nul plane" << endl;
1261 #endif
1262       NullifyAIS(anAIS);
1263       return;
1264     }
1265     ais->SetPlane(aplane);
1266   }
1267   anAIS = ais;
1268 }
1269
1270 //=======================================================================
1271 //function : ComputeMaxRadius
1272 //purpose  : 
1273 //=======================================================================
1274 void TPrsStd_ConstraintTools::ComputeMaxRadius (const Handle(TDataXtd_Constraint)& aConst,
1275                                                 Handle(AIS_InteractiveObject)& anAIS) 
1276 {
1277   Standard_Integer nbgeom = aConst->NbGeometries();
1278   if (nbgeom < 1) {
1279 #ifdef DEB
1280     cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: at least one constrainte is needed" << endl;    
1281 #endif
1282     NullifyAIS(anAIS);
1283     return;
1284   }
1285
1286   TopoDS_Shape shape1 ;
1287   GetOneShape (aConst,shape1);
1288   if (shape1.IsNull()) {
1289 #ifdef DEB
1290     cout << "TPrsStd_ConstraintTools::ComputeMaxradius: null shape" << endl;
1291 #endif
1292     NullifyAIS(anAIS);
1293     return;
1294   }
1295
1296   // POP on teste si ce n'est pas un compound
1297   if (shape1.ShapeType()==TopAbs_COMPOUND ||
1298       shape1.ShapeType()==TopAbs_COMPSOLID ||
1299       shape1.ShapeType()==TopAbs_SOLID ||
1300       shape1.ShapeType()==TopAbs_SHELL ) {
1301 #ifdef DEB
1302     cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: not good shape" << endl;
1303 #endif
1304     NullifyAIS(anAIS);
1305     return;
1306   }
1307
1308   if (IsFace(shape1))
1309     shape1 = GetFace(shape1);
1310
1311   Standard_Real val1;
1312   TCollection_ExtendedString txt;
1313   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1314
1315   //  Update de l'AIS
1316   Standard_Boolean isplanar(aConst->IsPlanar());
1317   if (isplanar) GetGoodShape(shape1);
1318
1319   Handle(AIS_MaxRadiusDimension) ais;
1320   if (!anAIS.IsNull()) {
1321     ais = Handle(AIS_MaxRadiusDimension)::DownCast(anAIS);
1322     if (ais.IsNull()) {
1323       ais = new AIS_MaxRadiusDimension (shape1,val1,txt);
1324     }
1325     else {
1326       ais->SetValue(val1);
1327       ais->SetFirstShape(shape1);
1328       ais->SetText(txt);    
1329     }
1330   }
1331   else ais = new AIS_MaxRadiusDimension (shape1,val1,txt);
1332
1333   if (isplanar) {
1334     Handle(Geom_Geometry) ageom2;
1335     GetGeom(aConst,ageom2);
1336     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1337     if (aplane.IsNull()) {
1338 #ifdef DEB
1339       cout << "TPrsStd_ConstraintTools::ComputeMaxRadius: nul plane" << endl;
1340 #endif
1341       NullifyAIS(anAIS);
1342       return;
1343     }
1344     ais->SetPlane(aplane);
1345   }
1346   anAIS = ais;
1347 }
1348
1349 //=======================================================================
1350 //function : ComputeEqualDistance
1351 //purpose  : 
1352 //=======================================================================
1353 void TPrsStd_ConstraintTools::ComputeEqualDistance(const Handle(TDataXtd_Constraint)& aConst,
1354                                                    Handle(AIS_InteractiveObject)& anAIS) 
1355 {
1356   Standard_Integer nbgeom = aConst->NbGeometries();
1357   if (nbgeom < 4) {
1358       cout << "TPrsStd_ConstraintTools::ComputeEqual: at least four geometries are needed" << endl;;
1359       NullifyAIS(anAIS);
1360       return;
1361     }
1362   TopoDS_Shape aShape1, aShape2, aShape3, aShape4;
1363   Handle(Geom_Geometry) aGeom;
1364   GetShapesAndGeom(aConst, aShape1, aShape2, aShape3, aShape4, aGeom);
1365    if (aShape1.IsNull()||aShape2.IsNull()||
1366        aShape3.IsNull()||aShape4.IsNull()) {
1367 #ifdef DEB
1368     cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : null shape" << endl;
1369 #endif
1370     NullifyAIS(anAIS);
1371     return;
1372   }
1373
1374   GetGoodShape(aShape1);
1375   GetGoodShape(aShape2);
1376   GetGoodShape(aShape3);
1377   GetGoodShape(aShape4);
1378   
1379   if (!CheckShapesPair(aShape1, aShape2) || 
1380       !CheckShapesPair(aShape3, aShape4)){
1381 #ifdef DEB
1382         cout << "TPrsStd_ConstraintTools::ComputeEqualDistance : at least one pair of shapes is incorrect"<<endl;
1383 #endif
1384         NullifyAIS(anAIS);
1385         return;
1386       }
1387
1388   //Get the plane
1389   Standard_Boolean IsPlanar(aConst->IsPlanar());
1390   Handle(Geom_Plane) aPlane ;
1391   if(IsPlanar) aPlane = Handle(Geom_Plane)::DownCast(aGeom) ; 
1392  
1393   if (!IsPlanar || aPlane.IsNull()) {
1394     //create the plane
1395 #ifdef DEB
1396     cout<< "The constraint plane is not assigned "<< endl;
1397 #endif
1398     NullifyAIS(anAIS);
1399     return;
1400   }
1401   
1402   //Update AIS
1403   Handle(AIS_EqualDistanceRelation) ais; 
1404   if (!anAIS.IsNull()) {
1405     {
1406       ais = Handle(AIS_EqualDistanceRelation)::DownCast(anAIS);
1407     
1408       if (ais.IsNull()) 
1409         ais = new AIS_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1410       
1411       else {
1412         ais->SetFirstShape(aShape1);
1413         ais->SetSecondShape(aShape2);
1414         ais->SetShape3(aShape3);
1415         ais->SetShape4(aShape4);
1416         ais->SetPlane(aPlane);
1417       }
1418     }
1419   }
1420   else ais = new AIS_EqualDistanceRelation(aShape1, aShape2, aShape3, aShape4, aPlane);
1421   
1422   anAIS = ais;  
1423
1424   return;
1425 }
1426
1427 //======================================================================
1428 // function : CheckShapesPair
1429 // purpose  : checks the types of two shapes. 
1430 //            If the types aShape1 and aShape2 are EDGE - EDGE,
1431 //                                              or EDGE - VERTEX,
1432 //                                              or VERTEX - VERTEX,
1433 //                                              or CIRCLE - CIRCLE,
1434 //                                              or CIRCLE - VERTEX,
1435 //            then function returns TRUE, otherwise FALSE.
1436 //======================================================================
1437 static Standard_Boolean CheckShapesPair(const TopoDS_Shape& aShape1, 
1438                                     const TopoDS_Shape& aShape2)
1439 {
1440   //Check whether the shapes form a correct pair.
1441   if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_EDGE)
1442     {
1443       BRepAdaptor_Curve aCurve1(TopoDS::Edge(aShape1));
1444       BRepAdaptor_Curve aCurve2(TopoDS::Edge(aShape2));
1445       if (aCurve1.GetType() == GeomAbs_Line && aCurve2.GetType() == GeomAbs_Line)
1446         { //Are lines parallel ?
1447           gp_Dir aDir1 = aCurve1.Line().Direction();
1448           gp_Dir aDir2 = aCurve2.Line().Direction();
1449           if (!(aDir1.IsParallel(aDir2, Precision::Confusion()))) {
1450 #ifdef DEB
1451             cout << " Lines are not parallel"<<endl;
1452 #endif
1453             return Standard_False;
1454           }
1455         }
1456       else if (aCurve1.GetType() == GeomAbs_Circle && aCurve2.GetType() == GeomAbs_Circle)
1457         {
1458           gp_Pnt aCntr1 = aCurve1.Circle().Location(); //get the circle center
1459           gp_Pnt aCntr2 = aCurve2.Circle().Location(); //get the circle center
1460           if (!aCntr1.IsEqual(aCntr2,Precision::Confusion())){
1461 #ifdef DEB
1462             cout << " Circles are not concentric"<<endl;
1463 #endif
1464             return Standard_False;
1465           }
1466         }
1467       else {
1468 #ifdef DEB
1469         cout << "Incorrect pair of curves "<<endl;
1470 #endif
1471         return Standard_False;
1472       }
1473     }
1474   else if ( aShape1.ShapeType() != TopAbs_VERTEX || aShape2.ShapeType() != TopAbs_VERTEX)
1475     {
1476       gp_Pnt aPnt;
1477       BRepAdaptor_Curve aCurve;
1478       if ( aShape1.ShapeType() == TopAbs_VERTEX) {
1479         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
1480         aCurve.Initialize(TopoDS::Edge(aShape2));
1481       }
1482       else {
1483         aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
1484         aCurve.Initialize(TopoDS::Edge(aShape1));
1485       }
1486       if ( aCurve.GetType() == GeomAbs_Circle)
1487         {
1488           gp_Pnt aCntr = aCurve.Circle().Location();
1489           if (!aCntr.IsEqual(aPnt, Precision::Confusion())){
1490 #ifdef DEB
1491             cout << " The point doesn't coincide with the circle center"<<endl;
1492 #endif
1493             return Standard_False;
1494           }
1495         }
1496     }
1497   return Standard_True;
1498 }
1499
1500 //=======================================================================
1501 //function : ComputeEqualRadius
1502 //purpose  : 
1503 //=======================================================================
1504 void TPrsStd_ConstraintTools::ComputeEqualRadius(const Handle(TDataXtd_Constraint)& aConst,
1505                                                  Handle(AIS_InteractiveObject)& anAIS) 
1506 {
1507   Standard_Integer nbgeom = aConst->NbGeometries();
1508   if (nbgeom < 2) {
1509 #ifdef DEB
1510     cout << "TPrsStd_ConstraintTools::ComputeEqualRadius: at least two geometries are needed" << endl;;
1511 #endif
1512     NullifyAIS(anAIS);
1513     return;
1514   }
1515   TopoDS_Shape shape1, shape2;
1516   Handle(Geom_Geometry) ageom3;
1517   
1518   GetShapesAndGeom(aConst, shape1, shape2, ageom3);
1519   if (shape1.IsNull()||shape2.IsNull()) {
1520 #ifdef DEB
1521     cout << "TPrsStd_ConstraintTools::ComputeEqualRadius : null shape" << endl;
1522 #endif
1523     NullifyAIS(anAIS);
1524     return;
1525   }
1526   
1527   //  Update AIS
1528   Standard_Boolean IsPlanar(aConst->IsPlanar());
1529  
1530   GetGoodShape(shape1);
1531   GetGoodShape(shape2);
1532   const TopoDS_Edge edge1 = TopoDS::Edge(shape1);
1533   const TopoDS_Edge edge2 = TopoDS::Edge(shape2);
1534   Handle(Geom_Plane) aplane ;
1535   
1536   if (IsPlanar) aplane = Handle(Geom_Plane)::DownCast(ageom3) ;
1537   
1538   if (!IsPlanar || aplane.IsNull()) {
1539     // check are the planes of edge1 and edge2 coincident
1540     BRepAdaptor_Curve aCurve( edge1 );
1541     Handle( Geom_Curve ) aProjCurve = aCurve.Curve().Curve();
1542     gp_Circ aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1543     gp_Ax3 anAx31(aCircle.Position()); //get the circle axis
1544     // get the circle plane 
1545     Handle(Geom_Plane) aPlane1 = new Geom_Plane (anAx31);
1546
1547     aCurve.Initialize(edge2);
1548     aProjCurve = aCurve.Curve().Curve();
1549     aCircle = (Handle( Geom_Circle )::DownCast( aProjCurve ))->Circ();
1550     gp_Ax3 anAx32(aCircle.Position()); //get the circle axis
1551     // get the circle plane 
1552     Handle(Geom_Plane) aPlane2 = new Geom_Plane (anAx32);
1553
1554     Standard_Real A, B, C ,D1, D2;
1555     aPlane1->Coefficients(A, B, C, D1);//Get normalized coefficients
1556     aPlane2->Coefficients(A, B, C, D2);//Get normalized coefficients
1557     const gp_Dir& aDir1 = anAx31.Direction();
1558     const gp_Dir& aDir2 = anAx32.Direction();
1559     
1560     if(Abs(D1 - D2) < Precision::Confusion() &&
1561        aDir1.IsParallel(aDir2, Precision::Confusion()))
1562       aplane = aPlane2;
1563     else {
1564 #ifdef DEB
1565       cout << "TPrsStd_ConstraintTools::ComputeRadiusRelation: nul plane" << endl;
1566 #endif
1567       NullifyAIS(anAIS);
1568       return;
1569     }
1570   }   
1571   Handle(AIS_EqualRadiusRelation) ais;
1572   if (!anAIS.IsNull()) {
1573     ais = Handle(AIS_EqualRadiusRelation)::DownCast(anAIS);
1574     
1575     if (ais.IsNull()) {
1576       ais = new AIS_EqualRadiusRelation(edge1, edge2, aplane);
1577       }
1578     else {
1579       ais->SetFirstShape(shape1);
1580       ais->SetSecondShape(shape2);
1581       ais->SetPlane(aplane);
1582     }
1583   }
1584   else {
1585     ais = new AIS_EqualRadiusRelation(edge1, edge2, aplane);
1586   }
1587   
1588   anAIS = ais;
1589 }
1590 //ota -- end --
1591
1592 //=======================================================================
1593 //function : ComputeDiameter
1594 //purpose  : 
1595 //=======================================================================
1596 void TPrsStd_ConstraintTools::ComputeDiameter(const Handle(TDataXtd_Constraint)& aConst,
1597                                              Handle(AIS_InteractiveObject)& anAIS) 
1598 {
1599   Standard_Integer nbgeom = aConst->NbGeometries();
1600   if (nbgeom < 1) {
1601 #ifdef DEB
1602     cout << "TPrsStd_ConstraintTools::ComputeDiameter: at least one constrainte is needed" << endl;;
1603 #endif
1604     NullifyAIS(anAIS);
1605     return;
1606   }
1607   TopoDS_Shape shape1 ;
1608   
1609   GetOneShape(aConst,shape1);
1610   if (shape1.IsNull()) {
1611 #ifdef DEB
1612     cout << "TPrsStd_ConstraintTools::ComputeDiameter : null shape" << endl;
1613 #endif
1614     NullifyAIS(anAIS);
1615     return;
1616   }
1617   Standard_Real val1;
1618   TCollection_ExtendedString txt;
1619   ComputeTextAndValue(aConst,val1,txt,Standard_False);
1620
1621   //  Update de l'AIS
1622   Standard_Boolean IsPlanar(aConst->IsPlanar());
1623   if (IsPlanar) GetGoodShape(shape1);
1624   Handle(AIS_DiameterDimension) ais;
1625   if (!anAIS.IsNull()) {
1626     ais = Handle(AIS_DiameterDimension)::DownCast(anAIS);
1627     if (ais.IsNull()) {
1628       ais = new AIS_DiameterDimension (shape1,val1,txt);
1629     }
1630     else {
1631       ais->SetFirstShape(shape1);
1632       ais->SetValue(val1);
1633       ais->SetText(txt);
1634     }
1635   }
1636   else ais = new AIS_DiameterDimension (shape1,val1,txt);
1637
1638   if (IsPlanar) {
1639     Handle(Geom_Geometry) ageom2;
1640     GetGeom(aConst,ageom2);
1641     Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1642     if (aplane.IsNull()) {
1643 #ifdef DEB
1644       cout << "TPrsStd_ConstraintTools::ComputeDiameter: nul plane" << endl;
1645 #endif
1646       NullifyAIS(anAIS);
1647       return;
1648     }
1649     ais->SetPlane(aplane);
1650   }
1651   anAIS = ais;
1652 }
1653
1654
1655 //=======================================================================
1656 //function : ComputeFix
1657 //purpose  : 
1658 //=======================================================================
1659 void TPrsStd_ConstraintTools::ComputeFix(const Handle(TDataXtd_Constraint)& aConst,
1660                                         Handle(AIS_InteractiveObject)& anAIS) 
1661 {
1662   Standard_Integer nbgeom = aConst->NbGeometries();
1663   if (nbgeom < 1) {
1664 #ifdef DEB
1665     cout << "TPrsStd_ConstraintTools::ComputeFix: at least one constrainte is needed" << endl;;
1666 #endif
1667     NullifyAIS(anAIS);
1668     return;
1669   }
1670   if (!aConst->IsPlanar()) {
1671 #ifdef DEB
1672     cout << "TPrsStd_ConstraintTools::ComputeFix: must be a planar constraint" << endl;;
1673 #endif
1674     NullifyAIS(anAIS);
1675     return;
1676   }
1677
1678   TopoDS_Shape shape1 ;
1679   Handle(Geom_Geometry) ageom2;
1680   
1681   GetOneShape(aConst,shape1);
1682   if (shape1.IsNull()) {
1683 #ifdef DEB
1684     cout << "TPrsStd_ConstraintTools::ComputeFix : null shape" << endl;
1685 #endif
1686     NullifyAIS(anAIS);
1687     return;
1688   }  
1689   GetGoodShape(shape1);
1690   GetGeom(aConst,ageom2);
1691   Handle(Geom_Plane) aplane = Handle(Geom_Plane)::DownCast(ageom2);
1692   if (aplane.IsNull()) {
1693 #ifdef DEB
1694     cout << "TPrsStd_ConstraintTools::ComputeFix: nul plane" << endl;
1695 #endif
1696     NullifyAIS(anAIS);
1697     return;
1698   }
1699   //  Update de l'AIS
1700   Handle(AIS_FixRelation) ais;
1701   if (!anAIS.IsNull()) {
1702     ais = Handle(AIS_FixRelation)::DownCast(anAIS);
1703     if (ais.IsNull()) {
1704       ais = new AIS_FixRelation (shape1,aplane);
1705     }
1706     else {
1707       ais->SetFirstShape(shape1);
1708       ais->SetPlane(aplane);
1709     }
1710   }
1711   else ais = new AIS_FixRelation (shape1,aplane);
1712
1713   anAIS = ais;
1714 }
1715
1716 //=======================================================================
1717 //function : ComputeOffset
1718 //purpose  : 
1719 //=======================================================================
1720 void TPrsStd_ConstraintTools::ComputeOffset (const Handle(TDataXtd_Constraint)& aConst,
1721                                             Handle(AIS_InteractiveObject)& anAIS) 
1722 {
1723   // Get plane for planar constraint
1724   Standard_Boolean is_planar (aConst->IsPlanar());
1725   Handle(Geom_Plane) aplane;      
1726   if (is_planar) {
1727     GetGeom (aConst,aplane);
1728     if (aplane.IsNull()) {
1729 #ifdef DEB
1730       cout << "TPrsStd_ConstraintTools::ComputeOffset: null plane" << endl;
1731 #endif
1732       NullifyAIS(anAIS);
1733       return;
1734     }
1735   }
1736
1737   // Get shapes
1738   TopoDS_Shape S1, S2;
1739   Standard_Integer nbgeom = aConst->NbGeometries();
1740   if (nbgeom == 1) {
1741     Handle(TNaming_NamedShape) ageom1 = aConst->GetGeometry(1);
1742     // c'est une shape qui contient les faces generees par les faces d'origines
1743     TNaming_Iterator It (ageom1);
1744     if (It.More()) {
1745       S1 = It.OldShape();
1746       S2 = It.NewShape();
1747     }
1748   }
1749   else
1750   if (nbgeom == 2)  {
1751     // Get geometry of the constraint
1752     GetTwoShapes (aConst,S1,S2);
1753   }
1754
1755   if (S1.IsNull() || S2.IsNull()) {
1756 #ifdef DEB
1757     cout << "TPrsStd_ConstraintTools::ComputeOffset: null shape" << endl;
1758 #endif
1759     NullifyAIS(anAIS);
1760     return;
1761   }
1762
1763
1764   Standard_Real val1;
1765   TCollection_ExtendedString txt;
1766   Handle(AIS_LengthDimension) ais;
1767   //Handle(AIS_Drawer) aDrawer;
1768   Standard_Boolean NotNull = Standard_False;
1769
1770   if (nbgeom == 1) {
1771       
1772     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1773   
1774     if (!anAIS.IsNull()) {
1775       ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
1776       NotNull = Standard_True; 
1777     }
1778    
1779     if (S1.ShapeType() == TopAbs_FACE && S2.ShapeType() == TopAbs_FACE) {
1780       if (ais.IsNull()) {
1781         ais = new AIS_LengthDimension (TopoDS::Face(S1),TopoDS::Face(S2),
1782                                        val1,txt);
1783       }
1784       else {
1785         ais->SetFirstShape(S1);
1786         ais->SetSecondShape(S2);
1787         ais->SetValue(val1);
1788         ais->SetText(txt);
1789       }
1790
1791       if (is_planar) ais->SetPlane (aplane);
1792       anAIS = ais;
1793       return;
1794     }
1795     else
1796     if (S1.ShapeType() == TopAbs_EDGE && S2.ShapeType() == TopAbs_EDGE) {
1797       // Find a plane for the dimension
1798       TopoDS_Edge OE = TopoDS::Edge(S1);
1799       BRepAdaptor_Curve CURVE(OE);
1800       if (CURVE.GetType() == GeomAbs_Line)  {
1801         // Works only with line !!
1802 //#ifndef DEB
1803         Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1804         gp_Lin OLin = ((Handle(Geom_Line)&) aGeomGeometry)->Lin();
1805 //#else
1806 //      gp_Lin OLin = ((Handle(Geom_Line)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Lin();
1807 //#endif
1808         TopoDS_Edge NE = TopoDS::Edge(S2);
1809         CURVE.Initialize (NE);
1810 //#ifndef DEB
1811         aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1812         gp_Lin NLin = ((Handle(Geom_Line)&)aGeomGeometry)->Lin();
1813 //#else
1814 //      gp_Lin NLin = ((Handle(Geom_Line)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Lin();
1815 //#endif
1816         gp_Dir TDir (NLin.Location().XYZ() - OLin.Location().XYZ());
1817         aplane = new Geom_Plane (NLin.Location(),NLin.Direction()^TDir);
1818
1819         if (ais.IsNull()) {
1820           ais = new AIS_LengthDimension (S1,S2,aplane,val1,txt);
1821         }
1822         else {
1823           ais->SetFirstShape(S1);
1824           ais->SetSecondShape(S2);
1825           ais->SetValue(val1);
1826           ais->SetText(txt);
1827           ais->SetPlane(aplane);
1828         }
1829         anAIS = ais;
1830         return;
1831       }
1832       else
1833       if (CURVE.GetType() == GeomAbs_Circle)  {
1834 //#ifndef DEB
1835         Handle_Geom_Geometry aGeomGeometry = CURVE.Curve().Curve()->Transformed(CURVE.Trsf()) ;
1836         gp_Ax1 ax = ((Handle(Geom_Circle)&) aGeomGeometry)->Circ().Axis();
1837 //#else
1838 //      gp_Ax1 ax = ((Handle(Geom_Circle)&) CURVE.Curve().Curve()->Transformed(CURVE.Trsf()))->Circ().Axis();
1839 //#endif
1840         aplane = new Geom_Plane (ax.Location(),ax.Direction());
1841         is_planar = Standard_True;
1842       }
1843     }
1844   }
1845
1846
1847   if (!is_planar)  {
1848     if (S1.ShapeType() == TopAbs_COMPOUND && 
1849         S2.ShapeType() == TopAbs_COMPOUND)  {
1850       // Resultat d'un offset - on reconstruit un wire pour determiner un plan
1851       TopoDS_Wire w1;
1852       BRep_Builder B;
1853       B.MakeWire (w1);
1854       TopExp_Explorer exp (S1,TopAbs_EDGE);
1855       for (;exp.More();exp.Next())
1856         B.Add (w1,exp.Current());
1857
1858       BRepBuilderAPI_MakeFace MkF (w1,Standard_True);
1859       if (MkF.IsDone())  {
1860 //#ifndef DEB
1861         Handle_Geom_Surface aGeomSurface = BRep_Tool::Surface(MkF.Face());
1862         aplane = (Handle(Geom_Plane)&) aGeomSurface ;
1863 //#else
1864 //      aplane = ((Handle(Geom_Plane)&) BRep_Tool::Surface(MkF.Face()));
1865 //#endif
1866         is_planar = Standard_True;
1867       }
1868     }
1869   }
1870
1871   if (is_planar) {
1872     ComputeTextAndValue (aConst,val1,txt,Standard_False);
1873     TopExp_Explorer EXP1 (S1,TopAbs_VERTEX);
1874     S1 = EXP1.Current();
1875     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(S1));
1876       
1877     TopoDS_Vertex nearest;
1878     Standard_Real dist(RealLast());
1879
1880     for (TopExp_Explorer EXP2(S2,TopAbs_VERTEX); EXP2.More(); EXP2.Next()) {
1881       const TopoDS_Vertex& current = TopoDS::Vertex(EXP2.Current());
1882       gp_Pnt curpnt = BRep_Tool::Pnt(current);
1883       Standard_Real curdist = P.SquareDistance(curpnt);
1884       if (curdist < dist) {
1885         nearest= current;
1886         dist = curdist;
1887       }
1888     }
1889     S2 = nearest;
1890     if( !anAIS.IsNull() ) NotNull = Standard_True; 
1891     ais = Handle(AIS_LengthDimension)::DownCast(anAIS);
1892     if (ais.IsNull()) {
1893       ais = new AIS_LengthDimension (S1,S2,aplane,val1,txt);
1894     }
1895     else {
1896       ais->SetFirstShape (S1);
1897       ais->SetSecondShape (S2);
1898       ais->SetValue(val1);
1899       ais->SetText(txt);
1900       ais->SetPlane(aplane);
1901     }
1902     anAIS = ais;
1903     return;
1904   }
1905
1906 #ifdef DEB
1907   cout << "TPrsStd_ConstraintTools::ComputeOffset: Case not implemented" << endl;
1908 #endif
1909   NullifyAIS(anAIS);
1910 }
1911
1912
1913 //=======================================================================
1914 //function : ComputePlacement
1915 //purpose  : 
1916 //=======================================================================
1917 void TPrsStd_ConstraintTools::ComputePlacement
1918 (const Handle(TDataXtd_Constraint)& aConst,
1919  Handle(AIS_InteractiveObject)& anAIS) 
1920 {
1921   Standard_Integer nbgeom = aConst->NbGeometries();
1922   if (nbgeom < 2) 
1923     Standard_ProgramError::Raise
1924       ("TPrsStd_ConstraintTools::ComputePlacement: at leat two constraints are needed");
1925   
1926   TopoDS_Shape shape1,shape2 ;
1927   GetTwoShapes(aConst,shape1,shape2);
1928   if (shape1.IsNull() || shape2.IsNull()) {
1929 #ifdef DEB
1930     cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << endl;
1931 #endif
1932     NullifyAIS(anAIS);
1933     return;
1934   }
1935   
1936   Standard_Real val1=0.0;
1937   TCollection_ExtendedString txt= " ";
1938   if (aConst->IsDimension()) {
1939     ComputeTextAndValue(aConst,val1,txt,Standard_False);
1940   }
1941   //  Update de l'AIS
1942   Handle(AIS_OffsetDimension) ais;
1943   if (anAIS.IsNull()) {
1944     ais = new AIS_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1945     ais->SetArrowSize(val1/20.);
1946   } else {
1947     ais = Handle(AIS_OffsetDimension)::DownCast(anAIS);
1948     if (ais.IsNull()) {
1949       ais = new AIS_OffsetDimension(GetFace(shape1),GetFace(shape2),val1,txt);
1950       ais->SetArrowSize(val1/20.);
1951     } else {
1952       ais->SetFirstShape(GetFace(shape1));
1953       ais->SetSecondShape(GetFace(shape2));
1954       ais->SetValue(val1);
1955       ais->SetText(txt);
1956       ais->SetArrowSize(val1/20.);
1957     }
1958   }
1959   if (GetFace(shape1).IsNull() || GetFace(shape2).IsNull()) ais.Nullify();
1960   anAIS = ais;
1961 }
1962
1963 //=======================================================================
1964 //function : ComputeOthers
1965 //purpose  : 
1966 //=======================================================================
1967 void TPrsStd_ConstraintTools::ComputeOthers
1968 (const Handle(TDataXtd_Constraint)& aConst,
1969  Handle(AIS_InteractiveObject)& anAIS) 
1970 {
1971 }
1972
1973 //=======================================================================
1974 //function : GetOneShape
1975 //purpose  : 
1976 //=======================================================================
1977 void TPrsStd_ConstraintTools::GetOneShape
1978 (const Handle(TDataXtd_Constraint)& aConst,
1979  TopoDS_Shape& aShape) 
1980 {
1981   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);
1982   if (!ageom1.IsNull()) aShape =  TNaming_Tool::CurrentShape(ageom1);
1983 }
1984
1985 //=======================================================================
1986 //function : GetTwoShapes
1987 //purpose  : 
1988 //=======================================================================
1989 void TPrsStd_ConstraintTools::GetTwoShapes
1990 (const Handle(TDataXtd_Constraint)& aConst,
1991  TopoDS_Shape& aShape1,
1992  TopoDS_Shape& aShape2) 
1993 {
1994   const Handle(TNaming_NamedShape)& ageom1 = aConst->GetGeometry(1);    
1995   if (!ageom1.IsNull()) aShape1 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(1));
1996   const Handle(TNaming_NamedShape)& ageom2 = aConst->GetGeometry(2);    
1997   if (!ageom2.IsNull()) aShape2 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(2));
1998 }
1999
2000 //=======================================================================
2001 //function : GetShapesAndGeom
2002 //purpose  : 
2003 //=======================================================================
2004 void TPrsStd_ConstraintTools::GetShapesAndGeom
2005 (const Handle(TDataXtd_Constraint)& aConst,
2006  TopoDS_Shape& aShape1,
2007  TopoDS_Shape& aShape2,
2008  Handle(Geom_Geometry)& aGeom) 
2009 {
2010   GetTwoShapes(aConst,aShape1,aShape2);
2011   GetGeom(aConst,aGeom);
2012 }
2013
2014 //=======================================================================
2015 //function : GetShapesAndGeom
2016 //purpose  : 
2017 //=======================================================================
2018 void TPrsStd_ConstraintTools::GetShapesAndGeom
2019 (const Handle(TDataXtd_Constraint)& aConst,
2020  TopoDS_Shape& aShape1,
2021  TopoDS_Shape& aShape2,
2022  TopoDS_Shape& aShape3,
2023  Handle(Geom_Geometry)& aGeom) 
2024 {
2025   GetTwoShapes(aConst,aShape1,aShape2);
2026   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);//ota: GetGeometry(2) was  
2027   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2028   GetGeom(aConst,aGeom);
2029 }
2030
2031 //=======================================================================
2032 //function : GetShapesAndGeom
2033 //purpose  : 
2034 //=======================================================================
2035 void TPrsStd_ConstraintTools::GetShapesAndGeom
2036   (const Handle(TDataXtd_Constraint)& aConst,
2037    TopoDS_Shape& aShape1,
2038    TopoDS_Shape& aShape2,
2039    TopoDS_Shape& aShape3,
2040    TopoDS_Shape& aShape4,
2041    Handle(Geom_Geometry)& aGeom) 
2042 {
2043   GetTwoShapes(aConst,aShape1, aShape2 );
2044   const Handle(TNaming_NamedShape)& ageom3 = aConst->GetGeometry(3);    
2045   if (!ageom3.IsNull()) aShape3 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(3));
2046   const Handle(TNaming_NamedShape)& ageom4 = aConst->GetGeometry(4); 
2047   if (!ageom4.IsNull()) aShape4 =  TNaming_Tool::CurrentShape(aConst->GetGeometry(4));
2048   GetGeom(aConst,aGeom);
2049 }
2050
2051 //=======================================================================
2052 //function : ComputeCoincident
2053 //purpose  : 
2054 //=======================================================================
2055 void TPrsStd_ConstraintTools::ComputeCoincident(const Handle(TDataXtd_Constraint)& aConst,
2056                                                Handle(AIS_InteractiveObject)& anAIS) 
2057 {
2058   Standard_Integer nbgeom = aConst->NbGeometries();
2059   if (nbgeom < 2) {
2060 #ifdef DEB
2061     cout << "TPrsStd_ConstraintTools::ComputeCoincident: at leat two constraintes are needed" << endl;
2062 #endif
2063     NullifyAIS(anAIS);
2064     return; 
2065   }
2066   
2067   if (!aConst->IsPlanar()) { 
2068 #ifdef DEB
2069     cout << "TPrsStd_ConstraintTools::ComputeCoincident: must be a planar constraint" << endl;
2070 #endif
2071     anAIS.Nullify() ; 
2072     return;
2073   }
2074   
2075   TopoDS_Shape shape1,shape2 ;
2076   Handle(Geom_Plane) aplane;
2077   GetShapesAndGeom(aConst,shape1,shape2,aplane);
2078   if (shape1.IsNull() || shape2.IsNull()) {
2079 #ifdef DEB
2080     cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul shape" << endl;
2081 #endif
2082     NullifyAIS(anAIS);
2083     return;
2084   }
2085
2086   GetGoodShape(shape1);
2087   GetGoodShape(shape2);
2088   if (aplane.IsNull()) {
2089 #ifdef DEB
2090     cout << "TPrsStd_ConstraintTools::ComputeCoincident: nul plane" << endl;
2091 #endif
2092     NullifyAIS(anAIS);
2093     return;
2094   }
2095   
2096   //  Update de l'AIS
2097   Handle(AIS_IdenticRelation) ais;
2098   if (anAIS.IsNull()) ais = new AIS_IdenticRelation(shape1,shape2,aplane);
2099   else {
2100     ais = Handle(AIS_IdenticRelation)::DownCast(anAIS);
2101     if (ais.IsNull()) {
2102       ais = new AIS_IdenticRelation(shape1,shape2,aplane);
2103     }
2104     else {
2105       ais->SetFirstShape(shape1);
2106       ais->SetSecondShape(shape2);
2107       ais->SetPlane(aplane);
2108     }
2109   }
2110   anAIS = ais;
2111 }
2112
2113 //=======================================================================
2114 //function : ComputeRound
2115 //purpose  : 
2116 //=======================================================================
2117 void TPrsStd_ConstraintTools::ComputeRound(const Handle(TDataXtd_Constraint)& aConst,
2118                                                Handle(AIS_InteractiveObject)& anAIS) 
2119 {
2120   Standard_Integer nbgeom = aConst->NbGeometries();
2121   if (nbgeom < 1) {
2122 #ifdef DEB
2123     cout << "TPrsStd_ConstraintTools::ComputeRound: at leat one geometry is needed" << endl;
2124 #endif
2125     NullifyAIS(anAIS);
2126     return; 
2127   }
2128   TopoDS_Shape shape1;
2129   GetOneShape (aConst,shape1);
2130   if (shape1.IsNull()) {
2131 #ifdef DEB
2132     cout << "TPrsStd_ConstraintTools::ComputePlacement: nul shape" << endl;
2133 #endif
2134     NullifyAIS(anAIS);
2135     return;
2136   }
2137   
2138   Standard_Real val1;
2139   TCollection_ExtendedString txt;
2140   ComputeTextAndValue(aConst,val1,txt,Standard_False);
2141   
2142   //  Update de l'AIS
2143   Handle(AIS_RadiusDimension) ais;
2144
2145   {
2146    try {
2147      OCC_CATCH_SIGNALS
2148      if (anAIS.IsNull()) ais = 
2149        new AIS_RadiusDimension(shape1,val1,txt);
2150      else {
2151        ais = Handle(AIS_RadiusDimension)::DownCast(anAIS);
2152        if (ais.IsNull()) {
2153          ais = new AIS_RadiusDimension(shape1,val1,txt);
2154        }
2155        else {
2156          ais->SetValue(val1);
2157          ais->SetText(txt);
2158          ais->SetFirstShape(shape1);
2159        }
2160      }
2161    }
2162    catch(Standard_Failure) {
2163      ais.Nullify();
2164    }
2165  }
2166   anAIS = ais;
2167 }
2168
2169 //=======================================================================
2170 //function : GetGeom
2171 //purpose  : 
2172 //=======================================================================
2173 void TPrsStd_ConstraintTools::GetGeom(const Handle(TDataXtd_Constraint)& aConst,
2174                                      Handle(Geom_Geometry)& aGeom)
2175 {  
2176   Handle(TNaming_NamedShape) atgeom = aConst->GetPlane();
2177   if (atgeom.IsNull()) {
2178 #ifdef DEB    
2179     cout<<"TPrsStd_ConstraintTools::GetGeom : aConst->GetPlane().IsNull()"<<endl;
2180 #endif
2181     return;
2182   }
2183   gp_Pln aplane;
2184   gp_Lin anaxis;
2185   gp_Pnt apoint;
2186   
2187   TDF_Label label = atgeom->Label();
2188
2189   Handle(TNaming_NamedShape) NS;
2190   if(label.FindAttribute(TNaming_NamedShape::GetID(),NS)){
2191     TopoDS_Shape s = TNaming_Tool::GetShape(NS);
2192     if(s.IsNull()) return;
2193   }
2194
2195   if (TDataXtd_Geometry::Plane(label,aplane)) aGeom =  new Geom_Plane(aplane);
2196   else if (TDataXtd_Geometry::Line(label,anaxis)) aGeom =  new Geom_Line(anaxis);
2197   else if (TDataXtd_Geometry::Point(label,apoint)) aGeom =  new Geom_CartesianPoint(apoint);
2198 #ifdef DEB
2199   else {
2200     cout << "TPrsStd_ConstraintTools::GetGeom no geom on label " << endl;
2201   }
2202 #endif  
2203 }
2204