-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//function : Execute
//purpose :
//=======================================================================
-Standard_Integer GEOMImpl_ProjectionDriver::Execute(LOGBOOK& log) const
+Standard_Integer GEOMImpl_ProjectionDriver::Execute(Handle(TFunction_Logbook)& log) const
{
if (Label().IsNull()) return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
Handle(GEOM_Function) aTargetFunction = TI.GetPlane();
if (aTargetFunction.IsNull()) return 0;
TopoDS_Shape aFaceShape = aTargetFunction->GetValue();
- //if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
- // Standard_ConstructionError::Raise
- // ("Projection aborted : the target shape is not a face");
- //}
-
- Standard_Real tol = 1.e-4;
if (anOriginal.ShapeType() == TopAbs_VERTEX) {
- if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
- Standard_ConstructionError::Raise
- ("Projection aborted : the target shape is not a face");
- }
- TopoDS_Face aFace = TopoDS::Face(aFaceShape);
- Handle(Geom_Surface) surface = BRep_Tool::Surface(aFace);
- double U1, U2, V1, V2;
- //surface->Bounds(U1, U2, V1, V2);
- BRepTools::UVBounds(aFace, U1, U2, V1, V2);
-
- // projector
- GeomAPI_ProjectPointOnSurf proj;
- proj.Init(surface, U1, U2, V1, V2, tol);
-
- gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(anOriginal));
- proj.Perform(aPnt);
- if (!proj.IsDone()) {
- Standard_ConstructionError::Raise
- ("Projection aborted : the algorithm failed");
- }
- int nbPoints = proj.NbPoints();
- if (nbPoints < 1) {
- Standard_ConstructionError::Raise("No solution found");
- }
-
Standard_Real U, V;
- proj.LowerDistanceParameters(U, V);
- gp_Pnt2d aProjPnt (U, V);
-
- // classifier
- BRepClass_FaceClassifier aClsf (aFace, aProjPnt, tol);
- if (aClsf.State() != TopAbs_IN && aClsf.State() != TopAbs_ON) {
- bool isSol = false;
- double minDist = RealLast();
- for (int i = 1; i <= nbPoints; i++) {
- Standard_Real Ui, Vi;
- proj.Parameters(i, Ui, Vi);
- aProjPnt = gp_Pnt2d(Ui, Vi);
- aClsf.Perform(aFace, aProjPnt, tol);
- if (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON) {
- isSol = true;
- double dist = proj.Distance(i);
- if (dist < minDist) {
- minDist = dist;
- U = Ui;
- V = Vi;
- }
- }
- }
- if (!isSol) {
- Standard_ConstructionError::Raise("No solution found");
- }
- }
-
- gp_Pnt surfPnt = surface->Value(U, V);
-
+ gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(anOriginal));
+ gp_Pnt surfPnt = GEOMUtils::ProjectPointOnFace(aPnt, aFaceShape, U, V);
aShape = BRepBuilderAPI_MakeVertex(surfPnt).Shape();
}
else {
try {
OrtProj.Build();
- } catch (Standard_Failure) {
- Handle(Standard_Failure) aFail = Standard_Failure::Caught();
- TCollection_AsciiString aMsg (aFail->GetMessageString());
+ } catch (Standard_Failure& aFail) {
+ TCollection_AsciiString aMsg (aFail.GetMessageString());
if (!aMsg.Length())
aMsg = "Projection aborted : possibly the source shape intersects the cylinder's axis";
Standard_ConstructionError::Raise(aMsg.ToCString());
// check that the result shape is an empty compound
// (IPAL22905: TC650: Projection on face dialog problems)
- if( !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND )
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND)
{
- TopoDS_Iterator anIter( aShape );
- if( !anIter.More() )
+ TopoDS_Iterator anIter(aShape);
+ if (!anIter.More())
Standard_ConstructionError::Raise("Projection aborted : empty compound produced");
+
+ if (anOriginal.ShapeType() == TopAbs_WIRE) {
+ // Make wire from resulting compound (Mantis issue 0023497)
+ TopTools_ListOfShape anEdgesList;
+ for (; anIter.More(); anIter.Next()) {
+ anEdgesList.Append(anIter.Value());
+ }
+ BRepBuilderAPI_MakeWire aMkWire;
+ aMkWire.Add(anEdgesList);
+ if (aMkWire.IsDone())
+ aShape = aMkWire.Wire();
+ }
}
}
if (aShape.IsNull()) return 0;
aFunction->SetValue(aShape);
-#if OCC_VERSION_MAJOR < 7
- log.SetTouched(Label());
-#else
log->SetTouched(Label());
-#endif
} else if (aType == PROJECTION_ON_WIRE) {
// Perform projection of point on a wire or an edge.
GEOMImpl_IProjection aProj (aFunction);
}
// Transform the curve to cylinder's parametric space.
-#if OCC_VERSION_MAJOR < 7
- GEOMUtils::Handle(HTrsfCurve2d) aTrsfCurve =
-#else
Handle(GEOMUtils::HTrsfCurve2d) aTrsfCurve =
-#endif
new GEOMUtils::HTrsfCurve2d(aCurve, aPar[0], aPar[1], aTrsf2d);
Approx_Curve2d aConv (aTrsfCurve, aPar[0], aPar[1],
aUResol, aVResol, GeomAbs_C1,
return aResult;
}
-OCCT_IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ProjectionDriver,GEOM_BaseDriver);
+IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ProjectionDriver,GEOM_BaseDriver)