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