// File: AIS_DiameterDimension.cdl // Created: Tue Dec 5 15:09:04 1996 // Modified Mon 12-january-98 // Author: Jacques MINOT/Odile Olivier/Sergey ZARITCHNY // , #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size // if any in all dimensions. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : Constructor //purpose : //======================================================================= AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, const Standard_Real aVal, const TCollection_ExtendedString& aText) :AIS_Relation(), myDiamSymbol(Standard_True) { myPosition = gp_Pnt(0.,0.,0.); myFShape = aShape; myVal = aVal; myText = aText; mySymbolPrs = DsgPrs_AS_LASTAR; myAutomaticPosition = Standard_True; myArrowSize = myVal / 100.; } //======================================================================= //function : Constructor //purpose : //======================================================================= AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, const Standard_Real aVal, const TCollection_ExtendedString& aText, const gp_Pnt& aPosition, const DsgPrs_ArrowSide aSymbolPrs, const Standard_Boolean aDiamSymbol, const Standard_Real anArrowSize) :AIS_Relation(), myDiamSymbol(aDiamSymbol) { myFShape = aShape; myVal = aVal; myText = aText; mySymbolPrs = aSymbolPrs; myPosition = aPosition; myAutomaticPosition = Standard_False; #ifdef BUC60915 SetArrowSize( anArrowSize ); #else myArrowSize = anArrowSize; #endif } //======================================================================= //function : Compute //purpose : //======================================================================= void AIS_DiameterDimension::Compute( const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/, const Handle(Prs3d_Presentation)& aPresentation, const Standard_Integer /*aMode*/) { aPresentation->Clear(); switch (myFShape.ShapeType()) { case TopAbs_FACE : { // compute one face case ComputeOneFaceDiameter (aPresentation); break; } case TopAbs_EDGE: { ComputeOneEdgeDiameter (aPresentation); break; } default: break; } } //======================================================================= //function : Compute //purpose : to avoid warning //======================================================================= void AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation) { // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)"); PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ; } //======================================================================= //function : Compute //purpose : to avoid warning //======================================================================= void AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager, const Handle(Graphic2d_GraphicObject)& aPresentation, const Standard_Integer aMode) { // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager, const Handle(Graphic2d_GraphicObject)& aPresentation, const Standard_Integer aMode)"); PrsMgr_PresentableObject::Compute( aPresentationManager ,aPresentation,aMode) ; } void AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation) { // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)"); PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ; } //======================================================================= //function : ComputeSelection //purpose : //======================================================================= void AIS_DiameterDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection, const Standard_Integer /*aMode*/) { Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7); own->SetShape(myFShape); if (!myIsAnArc) { gp_Pnt AttachmentPoint = myPosition; Standard_Real parat = ElCLib::Parameter(myCircle,AttachmentPoint); gp_Pnt ptoncirc = ElCLib::Value (parat,myCircle); // ligne de cote gp_Pnt center = myCircle.Location(); gp_Vec vecrap (ptoncirc,center); Standard_Real dist = center.Distance(AttachmentPoint); Standard_Real aRadius = myCircle.Radius(); Standard_Real inside = Standard_False; gp_Pnt pt1 = AttachmentPoint; if (dist < aRadius) { pt1 = ptoncirc; dist = aRadius; inside = Standard_True; } vecrap.Normalize(); vecrap *= (dist+aRadius); gp_Pnt OppositePoint = pt1.Translated(vecrap); if ( pt1.Distance(OppositePoint)>=Precision::Confusion()) { Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,pt1 ,OppositePoint); aSelection->Add(seg); } } else ComputeArcSelection(aSelection); // Text Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6)); Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own, myPosition.X(), myPosition.Y(), myPosition.Z(), myPosition.X() + size, myPosition.Y() + size, myPosition.Z() + size); aSelection->Add(box); } //========================================================================== // function : ComputeArcSelection // purpose : // //========================================================================== void AIS_DiameterDimension::ComputeArcSelection(const Handle(SelectMgr_Selection)& aSelection) { Standard_Real fpara; Standard_Real lpara; fpara = myFirstPar; lpara = myLastPar; Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7); gp_Pnt theCenter = myCircle.Location(); while (lpara > 2*PI) { fpara -= 2*PI; lpara -= 2*PI; } Standard_Real parat = ElCLib::Parameter(myCircle,myPosition); Standard_Boolean otherside(Standard_False); gp_Pnt attpoint = myPosition; if (!AIS::InDomain(fpara,lpara,parat)) { Standard_Real otherpar = parat + PI; if (otherpar > 2*PI) otherpar -= 2*PI; if (AIS::InDomain(fpara,lpara,otherpar)) { parat = otherpar; otherside = Standard_True; } else { Standard_Real ecartpar = Min(Abs(fpara-parat), Abs(lpara-parat)); Standard_Real ecartoth = Min(Abs(fpara-otherpar), Abs(lpara-otherpar)); if (ecartpar <= ecartoth) { if (parat < fpara) parat = fpara; else parat = lpara; } else { otherside = Standard_True; if (otherpar < fpara) parat = fpara; else parat = lpara; } gp_Pnt ptdir = ElCLib::Value(parat,myCircle); gp_Lin lsup(theCenter, gp_Dir(ptdir.XYZ()-theCenter.XYZ())); Standard_Real parpos = ElCLib::Parameter(lsup,myPosition); attpoint = ElCLib::Value(parpos,lsup); } } gp_Pnt ptoncirc = ElCLib::Value(parat,myCircle); gp_Lin L (theCenter,gp_Dir(attpoint.XYZ()-theCenter.XYZ())); gp_Pnt firstpoint = attpoint; gp_Pnt drawtopoint = ptoncirc; if (!otherside) { Standard_Real uatt = ElCLib::Parameter(L,attpoint); Standard_Real uptc = ElCLib::Parameter(L,ptoncirc); if (Abs(uatt) > Abs(uptc)) { drawtopoint = theCenter; } else { firstpoint = theCenter; } } Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,firstpoint,drawtopoint); aSelection->Add(seg); } //======================================================================= //function : ComputeOneFaceDiameter //purpose : //======================================================================= void AIS_DiameterDimension::ComputeOneFaceDiameter( const Handle(Prs3d_Presentation)& aPresentation) { //cout<<"AIS_DiameterDimension::ComputeOneFaceDiameter"<GetType() == GeomAbs_Line) ExpectedType = Standard_True; } else if (aSurfType == AIS_KOS_Extrusion) { BasisCurve = surf1.BasisCurve(); if ( BasisCurve->GetType() == GeomAbs_Circle ) ExpectedType = Standard_True; } if(!ExpectedType) { Standard_ConstructionError::Raise("AIS:: Not expected type of surface") ; return; } // Handle(Geom_Curve) aCurve; aCurve = aBasisSurf->VIso(vMid); if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) { myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ } else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) { Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); aCurve = tCurve->BasisCurve(); uFirst = tCurve->FirstParameter(); uLast = tCurve->LastParameter(); if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ } else { // compute a circle from 3 points on "aCurve" gp_Pnt P1, P2; surf1.D0(uFirst, vMid, P1); surf1.D0(uLast, vMid, P2); GC_MakeCircle mkCirc(P1, curPos, P2); myCircle = mkCirc.Value()->Circ(); } myCircle.SetRadius(myVal/2.); myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ gp_Vec v1(myCircle.Location(), curPos); v1.Normalize(); v1 = v1 * myVal*1.2; myPosition = myCircle.Location().Translated(v1); // IsArc ? gp_Pnt p1, p2; p1 = ElCLib::Value (uFirst, myCircle); p2 = ElCLib::Value (uLast, myCircle); if ( p1.IsEqual(p2, Precision::Confusion()) ) myIsAnArc = Standard_False; else myIsAnArc = Standard_True; myFirstPar = uFirst; myLastPar = uLast; // myPosition = curPos; myAutomaticPosition = Standard_True; if ( myIsSetBndBox ) myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(), myPosition ) ), myBndBox ); } else { // !AutomaticPosition curPos = myPosition; curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() ); myPosition = curPos; } Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect(); Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect(); // size #ifdef BUC60915 if( !myArrowSizeIsDefined ) { myArrowSize = Min(myArrowSize,myCircle.Radius()/5.); } arr->SetLength(myArrowSize); #else if (myCircle.Radius()/5. > myArrowSize) { arr->SetLength(myArrowSize); } else { arr->SetLength(myCircle.Radius()/5.); } #endif //cout<<"AIS_DiameterDimension:: add Prs"<Pln() ); } // size Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect(); Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect(); #ifdef BUC60915 if( !myArrowSizeIsDefined ) { myArrowSize = Min(myArrowSize,myCircle.Radius()/5.); } arr->SetLength(myArrowSize); #else if (myCircle.Radius()/5. > myArrowSize) { arr->SetLength(myArrowSize); } else { arr->SetLength(myCircle.Radius()/5.); } #endif DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol ); } //========================================================================== // function : ComputeArcDiameter // purpose : // //========================================================================== void AIS_DiameterDimension::ComputeArcDiameter( const Handle(Prs3d_Presentation)& aPresentation, const gp_Pnt& pfirst, const gp_Pnt& pend) { gp_Pnt center = myCircle.Location(); Standard_Real rad = myCircle.Radius(); gp_Pnt curpos; Standard_Real parfirst, parend; parfirst = ElCLib::Parameter(myCircle, pfirst); parend = ElCLib::Parameter(myCircle, pend); myFirstPar = parfirst; myLastPar = parend; if ( parfirst > parend) { parfirst -= 2*PI; } if (myAutomaticPosition) { Standard_Real pcurpos = (parfirst + parend)/2.; curpos = ElCLib::Value(pcurpos, myCircle); myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ gp_Dir vdir(gp_Vec(myCircle.Location(),curpos)); Standard_Real deport = rad * 1.2; curpos = center.Translated( gp_Vec(vdir)*deport ); SetPosition (curpos); myAutomaticPosition = Standard_True; if ( myIsSetBndBox ) myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(), myPosition ) ), myBndBox ); } else { curpos = myPosition; myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() ); } // size Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect(); Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect(); #ifdef BUC60915 if( !myArrowSizeIsDefined ) { myArrowSize = Min(myArrowSize,myCircle.Radius()/5.); } arr->SetLength(myArrowSize); #else if (myCircle.Radius()/5. > myArrowSize) { arr->SetLength(myArrowSize); } else { arr->SetLength(myCircle.Radius()/5.); } #endif // Display DsgPrs_DiameterPresentation::Add (aPresentation, myDrawer, myText, myPosition, myCircle, parfirst, parend, mySymbolPrs, myDiamSymbol); } //========================================================================== // function : ComputeOneEdgeDiameter // purpose : // //========================================================================== void AIS_DiameterDimension::ComputeOneEdgeDiameter(const Handle(Prs3d_Presentation)& aPresentation) { gp_Pnt ptfirst,ptend; Handle(Geom_Curve) curv; if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),curv,ptfirst,ptend)) return; Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(curv); if ( circ.IsNull()) return; myCircle = circ->Circ(); myCircle.SetRadius(myVal/2.); if ( ptfirst.IsEqual(ptend, Precision::Confusion()) ) { myIsAnArc = Standard_False; ComputeCircleDiameter(aPresentation); } else { myIsAnArc = Standard_True; ComputeArcDiameter(aPresentation,ptfirst,ptend ); } } //=================================================================== //function : CircleFromPlanarFace //purpose : if possible computes circle from planar face //======================================================================= static Standard_Boolean CircleFromPlanarFace(const TopoDS_Face& aFace, Handle(Geom_Curve)& aCurve, gp_Pnt & ptfirst, gp_Pnt & ptend) { TopExp_Explorer ExploEd( aFace, TopAbs_EDGE ); for ( ; ExploEd.More(); ExploEd.Next()) { TopoDS_Edge curedge = TopoDS::Edge( ExploEd.Current() ); if (AIS::ComputeGeometry(curedge, aCurve, ptfirst, ptend)) if(aCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) && !Handle(Geom_Circle)::DownCast(aCurve).IsNull()) return Standard_True; } return Standard_False; } //======================================================================= //function : ComputeOnePlanarFaceDiameter //purpose : //======================================================================= void AIS_DiameterDimension::ComputeOnePlanarFaceDiameter(const Handle(Prs3d_Presentation)& aPresentation) { gp_Pnt curPos ; #ifndef DEB Standard_Real parfirst =0., parend =0.; #else Standard_Real parfirst, parend; #endif if (myAutomaticPosition) { Handle(Geom_Curve) curv; gp_Pnt ptfirst,ptend; if( !CircleFromPlanarFace( TopoDS::Face( myFShape ), curv, ptfirst, ptend) ) { Standard_ConstructionError::Raise("AIS:: Curve is not a circle or is Null") ; return; } myCircle = Handle(Geom_Circle)::DownCast(curv)->Circ(); if ( ptfirst.IsEqual(ptend, Precision::Confusion()) ) myIsAnArc = Standard_False; else myIsAnArc = Standard_True; myCircle.SetRadius(myVal/2.);// BRepAdaptor_Surface surfAlgo (TopoDS::Face(myFShape)); myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ gp_Pnt center = myCircle.Location(); Standard_Real rad = myCircle.Radius(); Standard_Real deport = rad * 1.2; if(! myIsAnArc ) { // Circle gp_Dir xdir = myCircle.XAxis().Direction(); curPos = center.Translated( gp_Vec(xdir)*deport ); } else { // Arc parfirst = ElCLib::Parameter(myCircle, ptfirst); parend = ElCLib::Parameter(myCircle, ptend); if ( parfirst > parend) { parfirst -= 2*PI; } Standard_Real parcurPos = (parfirst + parend) * 0.5; curPos = ElCLib::Value(parcurPos, myCircle); gp_Vec v1( center, curPos ); v1.Normalize(); curPos = center.Translated( v1 * deport ); } myFirstPar = parfirst; myLastPar = parend; myPosition = curPos; myAutomaticPosition = Standard_True; if ( myIsSetBndBox ) myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(), myPosition ) ), myBndBox ); } else { // !myAutomaticPosition // Project point on the plane of face curPos = myPosition; curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() ); myPosition = curPos; } Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect(); Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect(); // size #ifdef BUC60915 if( !myArrowSizeIsDefined ) { myArrowSize = Min(myArrowSize,myCircle.Radius()/5.); } arr->SetLength(myArrowSize); #else if (myCircle.Radius()/5. > myArrowSize) { arr->SetLength(myArrowSize); } else { arr->SetLength(myCircle.Radius()/5.); } #endif if(! myIsAnArc ) DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol); else DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol ); }