mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-07 18:30:55 +03:00
1195 lines
39 KiB
C++
Executable File
1195 lines
39 KiB
C++
Executable File
// Created on: 1995-07-07
|
|
// Created by: Joelle CHAUVET
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
// Modified: Tue Oct 15 10:12:02 1996
|
|
// correction in BuildFilletEdge (PRO3529 : computation of dist)
|
|
// Modified: Tue Oct 22 09:23:11 1996
|
|
// correction in BuildFilletEdge (PRO5827 : computation of vec1)
|
|
// Modified: Tue Oct 22 09:23:11 1996
|
|
// new status in ComputeFillet for degenerated edges (PRO4896)
|
|
// Modified: Thu Dec 5 16:25:44 1996
|
|
// correction in BuildFilletEdge (PRO4896 : NewExtr1, NewExtr2)
|
|
// Modified: Tue Apr 22 16:25:44 1996
|
|
// correction in BuildFilletEdge (ID140047 : inside)
|
|
// Modified: Fri Oct 24 10:47:52 1997
|
|
// distinction point de tangence --> on arrete
|
|
// point de rebroussement --> on continue
|
|
// (PRO10404 : Ve3, Ve4)
|
|
// Modified: Tue Oct 28 11:55:53 1997
|
|
// construction de filletEdge avec les parametres U1 et Vv1
|
|
// au lieu des vertex (PRO10434)
|
|
// Modified: Tue Apr 7 14:35:58 1998
|
|
// construction de filletEdge avec les parametres U1 et Vv1
|
|
// ET les vertex NewExtr1, NewExtr2 sinon pb sur qq aretes
|
|
// degenerees (GER60069 + controle de PRO10434)
|
|
// Modified: Mon Jun 22 13:32:25 1998
|
|
// verification de la validite des parametres (PRO13078 partiel)
|
|
// Modified: Fri Sep 25 09:38:04 1998
|
|
// status = ChFi2d_NotAuthorized si les aretes ne sont pas
|
|
// des droites ou des cercles; fonction IsLineOrCircle
|
|
// (BUC60288)
|
|
|
|
|
|
|
|
#include <ChFi2d.hxx>
|
|
#include <ChFi2d_Builder.ixx>
|
|
|
|
#include <BRepAdaptor_Surface.hxx>
|
|
#include <BRepLib.hxx>
|
|
#include <BRepLib_MakeEdge.hxx>
|
|
#include <BRepLib_MakeFace.hxx>
|
|
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
|
|
#include <ElCLib.hxx>
|
|
|
|
#include <GccEnt_Position.hxx>
|
|
|
|
#include <Geom_Circle.hxx>
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom_Line.hxx>
|
|
#include <Geom_Plane.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
|
|
|
|
#include <Geom2d_TrimmedCurve.hxx>
|
|
#include <Geom2d_Circle.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
|
|
#include <Geom2dInt_GInter.hxx>
|
|
#include <Geom2dGcc_Circ2d2TanRad.hxx>
|
|
#include <Geom2dGcc_QualifiedCurve.hxx>
|
|
|
|
#include <IntRes2d_IntersectionPoint.hxx>
|
|
|
|
#include <gp_Pln.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Circ2d.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
|
|
#include <Precision.hxx>
|
|
|
|
#include <TopAbs_Orientation.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopLoc_Location.hxx>
|
|
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_IndexedMapOfShape.hxx>
|
|
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
|
|
static Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
|
|
const TopTools_IndexedMapOfShape& Map,
|
|
TopoDS_Edge& BasisEdge);
|
|
|
|
static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
|
|
const TopoDS_Face& F);
|
|
|
|
|
|
//=======================================================================
|
|
//function : ChFi2d_Builder
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
ChFi2d_Builder::ChFi2d_Builder()
|
|
{
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ChFi2d_Builder
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
ChFi2d_Builder::ChFi2d_Builder(const TopoDS_Face& F)
|
|
{
|
|
if (F.IsNull()) {
|
|
status = ChFi2d_NoFace;
|
|
return;
|
|
}
|
|
TopLoc_Location Loc;
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
|
|
// if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
|
|
if ( BRep_Tool::Surface( F, Loc)
|
|
-> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
|
|
newFace = refFace = F;
|
|
newFace.Orientation(TopAbs_FORWARD);
|
|
BRepLib::BuildCurves3d(newFace);
|
|
status = ChFi2d_Ready;
|
|
}
|
|
else status = ChFi2d_NotPlanar;
|
|
} // ChFi2d_Builder
|
|
|
|
//=======================================================================
|
|
//function : Init
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void ChFi2d_Builder::Init(const TopoDS_Face& F)
|
|
{
|
|
if (F.IsNull()) {
|
|
status = ChFi2d_NoFace;
|
|
return;
|
|
}
|
|
fillets.Clear();
|
|
chamfers.Clear();
|
|
history.Clear();
|
|
TopLoc_Location Loc;
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
|
|
// if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
|
|
if ( BRep_Tool::Surface( F, Loc)
|
|
-> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
|
|
newFace = refFace = F;
|
|
newFace.Orientation(TopAbs_FORWARD);
|
|
status = ChFi2d_Ready;
|
|
}
|
|
else status = ChFi2d_NotPlanar;
|
|
} // Init
|
|
|
|
|
|
//=======================================================================
|
|
//function : Init
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void ChFi2d_Builder::Init(const TopoDS_Face& RefFace,
|
|
const TopoDS_Face& ModFace)
|
|
{
|
|
if (RefFace.IsNull() || ModFace.IsNull()) {
|
|
status = ChFi2d_NoFace;
|
|
return;
|
|
}
|
|
fillets.Clear();
|
|
chamfers.Clear();
|
|
history.Clear();
|
|
TopLoc_Location loc;
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( RefFace, Loc);
|
|
// if (!surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
|
|
if ( ! BRep_Tool::Surface( RefFace, loc)
|
|
-> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
|
|
status = ChFi2d_NotPlanar;
|
|
return;
|
|
}
|
|
|
|
refFace = RefFace;
|
|
newFace = ModFace;
|
|
newFace.Orientation(TopAbs_FORWARD);
|
|
status = ChFi2d_Ready;
|
|
|
|
// Research in newFace all the edges which not appear in RefFace
|
|
// The sequence newEdges will contains this edges.
|
|
|
|
TopTools_SequenceOfShape newEdges;
|
|
TopTools_IndexedMapOfShape refEdgesMap;
|
|
TopExp::MapShapes(refFace, TopAbs_EDGE, refEdgesMap);
|
|
TopExp_Explorer ex(newFace, TopAbs_EDGE);
|
|
while (ex.More()){
|
|
const TopoDS_Edge& currentEdge = TopoDS::Edge(ex.Current());
|
|
if (!refEdgesMap.Contains(currentEdge))
|
|
newEdges.Append(currentEdge);
|
|
ex.Next();
|
|
} // while (ex ...
|
|
|
|
// update of history, fillets and chamfers fields
|
|
Standard_Integer i = 1;
|
|
Standard_Real first, last;
|
|
TopoDS_Edge basisEdge;
|
|
while ( i <= newEdges.Length()) {
|
|
const TopoDS_Edge& currentEdge = TopoDS::Edge(newEdges.Value(i));
|
|
if (IsIssuedFrom(currentEdge, refEdgesMap, basisEdge))
|
|
history.Bind(basisEdge, currentEdge);
|
|
else {
|
|
// this edge is a chamfer or a fillet
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(currentEdge, loc, first, last);
|
|
Handle(Geom_Curve) curve =
|
|
BRep_Tool::Curve(currentEdge, loc, first, last);
|
|
if (curve->IsKind(STANDARD_TYPE(Geom_Circle))) {
|
|
fillets.Append(currentEdge);
|
|
}
|
|
else if (curve->IsKind(STANDARD_TYPE(Geom_Line))) {
|
|
chamfers.Append(currentEdge);
|
|
}
|
|
else {
|
|
status = ChFi2d_InitialisationError;
|
|
return;
|
|
} // else ...
|
|
} // this edge is ...
|
|
i++;
|
|
} // while ...
|
|
} // Init
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsIssuedFrom
|
|
//purpose : Search in <Map> if <E> has a parent edge. If a parent has
|
|
// been find, this edge is returned in <BasisEdge>, else <E> is
|
|
// returned in <BasisEdge>.
|
|
//=======================================================================
|
|
Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
|
|
const TopTools_IndexedMapOfShape& Map,
|
|
TopoDS_Edge& BasisEdge)
|
|
{
|
|
TopLoc_Location loc1, loc2;
|
|
Standard_Real f1, L1, f2, L2;
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Curve)& c1 =
|
|
// BRep_Tool::Curve(E, loc1, f1, L1);
|
|
Handle(Geom_Curve) c1 = BRep_Tool::Curve(E, loc1, f1, L1);
|
|
|
|
for (Standard_Integer i = 1; i <= Map.Extent(); i++ ) {
|
|
const TopoDS_Edge& currentEdge = TopoDS::Edge(Map.FindKey(i));
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Curve)& c2 =
|
|
// BRep_Tool::Curve(currentEdge, loc2, f2, L2);
|
|
Handle(Geom_Curve) c2 = BRep_Tool::Curve(currentEdge, loc2, f2, L2);
|
|
if (c1 == c2 &&
|
|
(((f1 > f2 && f1 < L2) || (L1 > f2 && L1 < L2) ) ||
|
|
( (f1 > L2 && f1 < f2) || (L1 > L2 && L1 < f2) )) ) {
|
|
BasisEdge = currentEdge;
|
|
BasisEdge.Orientation(E.Orientation());
|
|
return Standard_True;
|
|
} // if (c1 == c2
|
|
} // for (Standard_Integer i ...
|
|
|
|
return Standard_False;
|
|
} // IsIssuedFrom
|
|
|
|
|
|
//=======================================================================
|
|
//function : AddFillet
|
|
//purpose :
|
|
//=======================================================================
|
|
TopoDS_Edge ChFi2d_Builder::AddFillet(const TopoDS_Vertex& V,
|
|
const Standard_Real Radius)
|
|
{
|
|
TopoDS_Edge adjEdge1, adjEdge2, basisEdge1, basisEdge2;
|
|
TopoDS_Edge adjEdge1Mod, adjEdge2Mod, fillet;
|
|
status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
|
|
if (status == ChFi2d_ConnexionError) return fillet;
|
|
|
|
if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
|
|
IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
|
|
status = ChFi2d_NotAuthorized;
|
|
return fillet;
|
|
} // if (IsAFillet ...
|
|
|
|
if (!IsLineOrCircle(adjEdge1,newFace)
|
|
|| !IsLineOrCircle(adjEdge2,newFace) ) {
|
|
status = ChFi2d_NotAuthorized;
|
|
return fillet;
|
|
} // if (!IsLineOrCircle ...
|
|
|
|
ComputeFillet(V, adjEdge1, adjEdge2, Radius,
|
|
adjEdge1Mod, adjEdge2Mod, fillet);
|
|
if (status == ChFi2d_IsDone
|
|
|| status == ChFi2d_FirstEdgeDegenerated
|
|
|| status == ChFi2d_LastEdgeDegenerated
|
|
|| status == ChFi2d_BothEdgesDegenerated) {
|
|
BuildNewWire(adjEdge1, adjEdge2, adjEdge1Mod, fillet, adjEdge2Mod);
|
|
basisEdge1 = BasisEdge(adjEdge1);
|
|
basisEdge2 = BasisEdge(adjEdge2);
|
|
UpDateHistory(basisEdge1, basisEdge2,
|
|
adjEdge1Mod, adjEdge2Mod, fillet, 1);
|
|
status = ChFi2d_IsDone;
|
|
return TopoDS::Edge(fillets.Value(fillets.Length()));
|
|
}
|
|
return fillet;
|
|
} // AddFillet
|
|
|
|
//=======================================================================
|
|
//function : ModifyFillet
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Edge ChFi2d_Builder::ModifyFillet(const TopoDS_Edge& Fillet,
|
|
const Standard_Real Radius)
|
|
{
|
|
TopoDS_Vertex aVertex = RemoveFillet(Fillet);
|
|
TopoDS_Edge aFillet = AddFillet(aVertex, Radius);
|
|
return aFillet;
|
|
} // ModifyFillet
|
|
|
|
//=======================================================================
|
|
//function : RemoveFillet
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Vertex ChFi2d_Builder::RemoveFillet(const TopoDS_Edge& Fillet)
|
|
{
|
|
TopoDS_Vertex commonVertex;
|
|
Standard_Integer i = 1;
|
|
Standard_Integer IsFind = Standard_False;
|
|
while (i <= fillets.Length()) {
|
|
const TopoDS_Edge& aFillet = TopoDS::Edge(fillets.Value(i));
|
|
if (aFillet.IsSame(Fillet)) {
|
|
fillets.Remove(i);
|
|
IsFind = Standard_True;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
if (!IsFind) return commonVertex;
|
|
|
|
|
|
TopoDS_Vertex firstVertex, lastVertex;
|
|
TopExp::Vertices(Fillet, firstVertex, lastVertex);
|
|
|
|
|
|
TopoDS_Edge adjEdge1, adjEdge2;
|
|
status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
|
|
adjEdge1, adjEdge2);
|
|
if (status == ChFi2d_ConnexionError) return commonVertex;
|
|
|
|
TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
|
|
// E1 and E2 are the adjacent edges to Fillet
|
|
|
|
if (adjEdge1.IsSame(Fillet)) E1 = adjEdge2;
|
|
else E1 = adjEdge1;
|
|
basisEdge1 = BasisEdge(E1);
|
|
status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
|
|
if (status == ChFi2d_ConnexionError) return commonVertex;
|
|
if (adjEdge1.IsSame(Fillet)) E2 = adjEdge2;
|
|
else E2 = adjEdge1;
|
|
basisEdge2 = BasisEdge(E2);
|
|
TopoDS_Vertex connectionE1Fillet, connectionE2Fillet;
|
|
Standard_Boolean hasConnection =
|
|
ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
|
|
if (!hasConnection) {
|
|
status = ChFi2d_ConnexionError;
|
|
return commonVertex;
|
|
}
|
|
hasConnection = ChFi2d::CommonVertex(E1, Fillet, connectionE1Fillet);
|
|
if (!hasConnection) {
|
|
status = ChFi2d_ConnexionError;
|
|
return commonVertex;
|
|
}
|
|
hasConnection = ChFi2d::CommonVertex(E2, Fillet, connectionE2Fillet);
|
|
if (!hasConnection) {
|
|
status = ChFi2d_ConnexionError;
|
|
return commonVertex;
|
|
}
|
|
|
|
// rebuild edges on wire
|
|
TopoDS_Edge newEdge1, newEdge2;
|
|
TopoDS_Vertex v, v1, v2;
|
|
BRepLib_MakeEdge makeEdge;
|
|
TopLoc_Location loc;
|
|
Standard_Real first, last;
|
|
|
|
TopExp::Vertices(E1, firstVertex, lastVertex);
|
|
TopExp::Vertices(basisEdge1, v1, v2);
|
|
if (v1.IsSame(commonVertex)) v = v2;
|
|
else v = v1;
|
|
|
|
if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
|
|
// It means the edge support only one fillet. In this case
|
|
// the new edge must be the basis edge.
|
|
newEdge1 = basisEdge1;
|
|
else {
|
|
// It means the edge support one fillet on each end.
|
|
if (firstVertex.IsSame(connectionE1Fillet)) {
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E1, loc, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
|
|
makeEdge.Init(curve, commonVertex, lastVertex);
|
|
newEdge1 = makeEdge.Edge();
|
|
newEdge1.Orientation(E1.Orientation());
|
|
newEdge1.Location(E1.Location());
|
|
} // if (firstVertex ...
|
|
else if (lastVertex.IsSame(connectionE1Fillet)) {
|
|
// syntax wrong on NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E1, loc, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
|
|
makeEdge.Init(curve, firstVertex, commonVertex);
|
|
newEdge1 = makeEdge.Edge();
|
|
newEdge1.Orientation(E1.Orientation());
|
|
newEdge1.Location(E1.Location());
|
|
} // else if (lastVertex ...
|
|
} // else ...
|
|
|
|
TopExp::Vertices(basisEdge2, v1, v2);
|
|
if (v1.IsSame(commonVertex)) v = v2;
|
|
else v = v1;
|
|
|
|
TopExp::Vertices(E2, firstVertex, lastVertex);
|
|
if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
|
|
// It means the edge support only one fillet. In this case
|
|
// the new edge must be the basis edge.
|
|
newEdge2 = basisEdge2;
|
|
else {
|
|
// It means the edge support one fillet on each end.
|
|
if (firstVertex.IsSame(connectionE2Fillet)) {
|
|
// syntax wrong on NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E2, loc, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
|
|
makeEdge.Init(curve, commonVertex, lastVertex);
|
|
newEdge2 = makeEdge.Edge();
|
|
newEdge2.Orientation(E2.Orientation());
|
|
newEdge2.Location(E2.Location());
|
|
} // if (firstVertex ...
|
|
else if (lastVertex.IsSame(connectionE2Fillet)) {
|
|
// syntax wrong on NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E2, loc, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
|
|
makeEdge.Init(curve, firstVertex, commonVertex);
|
|
newEdge2 = makeEdge.Edge();
|
|
newEdge2.Orientation(E2.Orientation());
|
|
newEdge2.Location(E2.Location());
|
|
} // else if (lastVertex ...
|
|
} // else ...
|
|
|
|
// rebuild the newFace
|
|
TopExp_Explorer Ex(newFace, TopAbs_EDGE);
|
|
TopoDS_Wire newWire;
|
|
|
|
BRep_Builder B;
|
|
B.MakeWire(newWire);
|
|
|
|
while (Ex.More()) {
|
|
const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
|
|
if (!theEdge.IsSame(E1) &&
|
|
!theEdge.IsSame(E2) &&
|
|
!theEdge.IsSame(Fillet))
|
|
B.Add(newWire, theEdge);
|
|
else {
|
|
if (theEdge == E1)
|
|
B.Add(newWire, newEdge1);
|
|
else if (theEdge == E2)
|
|
B.Add(newWire, newEdge2);
|
|
} // else
|
|
Ex.Next();
|
|
} // while ...
|
|
BRepAdaptor_Surface Adaptor3dSurface(refFace);
|
|
BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
|
|
newFace.Nullify();
|
|
newFace = mFace;
|
|
|
|
UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
|
|
|
|
return commonVertex;
|
|
} // RemoveFillet
|
|
|
|
|
|
//=======================================================================
|
|
//function : ComputeFillet
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void ChFi2d_Builder::ComputeFillet(const TopoDS_Vertex& V,
|
|
const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const Standard_Real Radius,
|
|
TopoDS_Edge& TrimE1,
|
|
TopoDS_Edge& TrimE2,
|
|
TopoDS_Edge& Fillet)
|
|
{
|
|
TopoDS_Vertex newExtr1, newExtr2;
|
|
Standard_Boolean Degen1, Degen2;
|
|
Fillet = BuildFilletEdge(V, E1, E2, Radius, newExtr1, newExtr2);
|
|
if ( status != ChFi2d_IsDone) return;
|
|
TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
|
|
TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
|
|
if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
|
|
if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
|
|
if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
|
|
} // ComputeFillet
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : BuildNewWire
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void ChFi2d_Builder::BuildNewWire (const TopoDS_Edge& OldE1,
|
|
const TopoDS_Edge& OldE2,
|
|
const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& Fillet,
|
|
const TopoDS_Edge& E2)
|
|
{
|
|
|
|
Standard_Boolean aClosedStatus = Standard_True;
|
|
|
|
TopExp_Explorer Ex(refFace, TopAbs_WIRE);
|
|
while (Ex.More()) {
|
|
const TopoDS_Wire& aWire = TopoDS::Wire(Ex.Current());
|
|
aClosedStatus = aWire.Closed();
|
|
break;
|
|
}
|
|
|
|
|
|
Standard_Boolean filletIsAdded = Standard_False;
|
|
|
|
Ex.Init(newFace, TopAbs_EDGE);
|
|
TopoDS_Wire newWire;
|
|
BRep_Builder B;
|
|
B.MakeWire(newWire);
|
|
|
|
while (Ex.More()) {
|
|
const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
|
|
if (!theEdge.IsSame(OldE1) && !theEdge.IsSame(OldE2)) {
|
|
B.Add(newWire, theEdge);
|
|
}
|
|
else {
|
|
if (theEdge == OldE1) {
|
|
if (status != ChFi2d_FirstEdgeDegenerated
|
|
&& status != ChFi2d_BothEdgesDegenerated) {
|
|
B.Add(newWire, E1);
|
|
}
|
|
if ( !filletIsAdded) {
|
|
B.Add(newWire, Fillet);
|
|
filletIsAdded = Standard_True;
|
|
} // if ( !filletIsAdded ...
|
|
} // if (theEdge == ...
|
|
else {
|
|
if (status != ChFi2d_LastEdgeDegenerated
|
|
&& status != ChFi2d_BothEdgesDegenerated) {
|
|
B.Add(newWire, E2);
|
|
}
|
|
if ( !filletIsAdded) {
|
|
B.Add(newWire, Fillet);
|
|
filletIsAdded = Standard_True;
|
|
}// if ( !filletIsAdded ...
|
|
} // else ...
|
|
} // else ...
|
|
Ex.Next();
|
|
} // while ...
|
|
|
|
newWire.Closed(aClosedStatus);
|
|
BRepAdaptor_Surface Adaptor3dSurface(refFace);
|
|
BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
|
|
newFace = mFace;
|
|
|
|
} // BuildNewWire
|
|
|
|
|
|
//=======================================================================
|
|
//function : BuildNewEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
|
|
const TopoDS_Vertex& OldExtr,
|
|
const TopoDS_Vertex& NewExtr) const
|
|
{
|
|
BRepLib_MakeEdge makeEdge;
|
|
TopLoc_Location loc;
|
|
Standard_Real first, last;
|
|
TopoDS_Vertex firstVertex, lastVertex;
|
|
TopExp::Vertices(E1, firstVertex, lastVertex);
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E1, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
|
|
if (firstVertex.IsSame(OldExtr))
|
|
makeEdge.Init(curve, NewExtr, lastVertex);
|
|
else
|
|
makeEdge.Init(curve, firstVertex, NewExtr);
|
|
TopoDS_Edge anEdge = makeEdge;
|
|
anEdge.Orientation(E1.Orientation());
|
|
// anEdge.Location(E1.Location());
|
|
return anEdge;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : BuildNewEdge
|
|
//purpose : special flag if the new edge is degenerated
|
|
//=======================================================================
|
|
|
|
TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
|
|
const TopoDS_Vertex& OldExtr,
|
|
const TopoDS_Vertex& NewExtr,
|
|
Standard_Boolean& IsDegenerated) const
|
|
{
|
|
BRepLib_MakeEdge makeEdge;
|
|
TopLoc_Location loc;
|
|
Standard_Real first, last;
|
|
IsDegenerated = Standard_False;
|
|
TopoDS_Vertex firstVertex, lastVertex;
|
|
TopExp::Vertices(E1, firstVertex, lastVertex);
|
|
gp_Pnt Pnew = BRep_Tool::Pnt(NewExtr);
|
|
Standard_Boolean PonctualEdge = Standard_False;
|
|
Standard_Real Tol = Precision::Confusion();
|
|
// syntax wrong on NT
|
|
// const Handle(Geom_Curve)& curve =
|
|
// BRep_Tool::Curve(E1, first, last);
|
|
Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
|
|
if (firstVertex.IsSame(OldExtr)) {
|
|
makeEdge.Init(curve, NewExtr, lastVertex);
|
|
gp_Pnt PV = BRep_Tool::Pnt(lastVertex);
|
|
PonctualEdge = (Pnew.Distance(PV)<Tol);
|
|
}
|
|
else {
|
|
makeEdge.Init(curve, firstVertex, NewExtr);
|
|
gp_Pnt PV = BRep_Tool::Pnt(firstVertex);
|
|
PonctualEdge = (Pnew.Distance(PV)<Tol);
|
|
}
|
|
TopoDS_Edge anEdge;
|
|
BRepLib_EdgeError error = makeEdge.Error();
|
|
if (error==BRepLib_LineThroughIdenticPoints || PonctualEdge) {
|
|
IsDegenerated = Standard_True;
|
|
anEdge = E1;
|
|
}
|
|
else {
|
|
anEdge = makeEdge;
|
|
anEdge.Orientation(E1.Orientation());
|
|
// anEdge.Location(E1.Location());
|
|
}
|
|
return anEdge;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : UpDateHistory
|
|
//purpose :
|
|
//=======================================================================
|
|
void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const TopoDS_Edge& TrimE1,
|
|
const TopoDS_Edge& TrimE2,
|
|
const TopoDS_Edge& NewEdge,
|
|
const Standard_Integer Id)
|
|
{
|
|
if (Id == 1) // the new edge is a fillet
|
|
fillets.Append(NewEdge);
|
|
else // the new edge is a chamfer
|
|
chamfers.Append(NewEdge);
|
|
if (history.IsBound(E1)) history.UnBind(E1);
|
|
if ( status != ChFi2d_FirstEdgeDegenerated
|
|
&& status != ChFi2d_BothEdgesDegenerated) {
|
|
if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
|
|
}
|
|
if (history.IsBound(E2)) history.UnBind(E2);
|
|
if ( status != ChFi2d_LastEdgeDegenerated
|
|
&& status != ChFi2d_BothEdgesDegenerated) {
|
|
if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
|
|
}
|
|
} // UpDateHistory
|
|
|
|
|
|
//=======================================================================
|
|
//function : UpDateHistory
|
|
//purpose :
|
|
//=======================================================================
|
|
void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
|
|
const TopoDS_Edge& E2,
|
|
const TopoDS_Edge& TrimE1,
|
|
const TopoDS_Edge& TrimE2)
|
|
{
|
|
|
|
|
|
if (history.IsBound(E1)) history.UnBind(E1);
|
|
if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
|
|
if (history.IsBound(E2)) history.UnBind(E2);
|
|
if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
|
|
} // UpDateHistory
|
|
|
|
|
|
//=======================================================================
|
|
//function : BasisEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const
|
|
{
|
|
TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history);
|
|
TopoDS_Edge anEdge;
|
|
while (iterator.More()) {
|
|
anEdge = TopoDS::Edge(iterator.Value());
|
|
if (anEdge.IsSame(E)) {
|
|
const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key());
|
|
return anotherEdge;
|
|
} // if (anEdge.IsSame ...
|
|
iterator.Next();
|
|
} // while (Iterator.More ...
|
|
return E;
|
|
} // BasisEdge
|
|
|
|
|
|
//=======================================================================
|
|
//function : BuildFilletEdge
|
|
//purpose :
|
|
//=======================================================================
|
|
TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V,
|
|
const TopoDS_Edge& AdjEdge1,
|
|
const TopoDS_Edge& AdjEdge2,
|
|
const Standard_Real Radius,
|
|
TopoDS_Vertex& NewExtr1,
|
|
TopoDS_Vertex& NewExtr2)
|
|
{
|
|
TopoDS_Edge E1, E2;
|
|
E1 = AdjEdge1;
|
|
E2 = AdjEdge2;
|
|
TopoDS_Vertex V1 = TopExp::FirstVertex(E1);
|
|
TopoDS_Vertex V2 = TopExp::LastVertex(E1);
|
|
TopoDS_Vertex V3 = TopExp::FirstVertex(E2);
|
|
TopoDS_Vertex V4 = TopExp::LastVertex(E2);
|
|
|
|
//========================================================================
|
|
// The first arc is found. +
|
|
//========================================================================
|
|
|
|
TopAbs_Orientation O1,O2;
|
|
TopAbs_Orientation OE1,OE2;
|
|
OE1 = E1.Orientation();
|
|
OE2 = E2.Orientation();
|
|
E1.Orientation(TopAbs_FORWARD);
|
|
E2.Orientation(TopAbs_FORWARD);
|
|
TopoDS_Shape aLocalShape = E1.EmptyCopied();
|
|
TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape);
|
|
aLocalShape = E2.EmptyCopied();
|
|
TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape);
|
|
// TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied());
|
|
// TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied());
|
|
Standard_Real param1,param2,param3,param4;
|
|
|
|
//========================================================================
|
|
// Save non-modified parts of edges concerned. +
|
|
//========================================================================
|
|
|
|
if (V1.IsSame(V)) {
|
|
param1 = BRep_Tool::Parameter(V1,E1);
|
|
param2 = BRep_Tool::Parameter(V2,E1);
|
|
O1 = V2.Orientation();
|
|
}
|
|
else {
|
|
param1 = BRep_Tool::Parameter(V2,E1);
|
|
param2 = BRep_Tool::Parameter(V1,E1);
|
|
O1 = V1.Orientation();
|
|
}
|
|
if (V3.IsSame(V)) {
|
|
param3 = BRep_Tool::Parameter(V3,E2);
|
|
param4 = BRep_Tool::Parameter(V4,E2);
|
|
O2 = V4.Orientation();
|
|
}
|
|
else {
|
|
param3 = BRep_Tool::Parameter(V4,E2);
|
|
param4 = BRep_Tool::Parameter(V3,E2);
|
|
O2 = V3.Orientation();
|
|
}
|
|
|
|
//========================================================================
|
|
// Restore geometric supports. +
|
|
//========================================================================
|
|
|
|
Handle(Geom2d_Curve) C1,C2;
|
|
Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2;
|
|
Standard_Real PPU1,PPU2;
|
|
C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1);
|
|
C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2);
|
|
|
|
//========================================================================
|
|
// Determination of the face for fillet. +
|
|
//========================================================================
|
|
|
|
gp_Pnt2d p;
|
|
gp_Vec2d Ve1,Ve2;
|
|
gp_Vec2d Ve3,Ve4;
|
|
Standard_Boolean Sens1 , Sens2;
|
|
|
|
Handle(Geom2d_Curve) basisC1,basisC2;
|
|
Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
|
|
if (!T1.IsNull())
|
|
basisC1 = Handle(Geom2d_Curve)::DownCast(T1->BasisCurve());
|
|
else
|
|
basisC1 = Handle(Geom2d_Curve)::DownCast(C1);
|
|
Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
|
|
if (!T2.IsNull())
|
|
basisC2 = Handle(Geom2d_Curve)::DownCast(T2->BasisCurve());
|
|
else
|
|
basisC2 = Handle(Geom2d_Curve)::DownCast(C2);
|
|
|
|
if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
|
|
Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
|
|
ElCLib::D1(param1,CC1->Circ2d(),p,Ve1);
|
|
Sens1 = (CC1->Circ2d()).IsDirect();
|
|
} // if (C1->DynamicType() ...
|
|
else {
|
|
Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
|
|
ElCLib::D1(param1,CC1->Lin2d(),p,Ve1);
|
|
Sens1=Standard_True;
|
|
} // else ...
|
|
if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
|
|
Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2);
|
|
ElCLib::D1(param3,CC2->Circ2d(),p,Ve2);
|
|
Sens2 = (CC2->Circ2d()).IsDirect();
|
|
} // if if (C2->DynamicType() ...
|
|
else {
|
|
Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2);
|
|
ElCLib::D1(param3,CC2->Lin2d(),p,Ve2);
|
|
Sens2=Standard_True;
|
|
} // else ...
|
|
|
|
TopoDS_Edge filletEdge;
|
|
|
|
Standard_Real cross = Ve1.Crossed(Ve2);
|
|
Ve3 = Ve1;
|
|
Ve4 = Ve2;
|
|
|
|
// processing of tangency or downcast point
|
|
if (Ve1.IsParallel(Ve2,Precision::Angular())) {
|
|
// Ve1 and Ve2 are parallel : cross at 0
|
|
cross = 0.;
|
|
if (param1<param2) {
|
|
Ve3 = -Ve1;
|
|
}
|
|
if (param3>param4) {
|
|
Ve4 = -Ve2;
|
|
}
|
|
|
|
if (! Ve4.IsOpposite(Ve3,Precision::Angular())) {
|
|
// There is a true tangency point and the calculation is stopped
|
|
status = ChFi2d_TangencyError;
|
|
return filletEdge;
|
|
}
|
|
// Otherwise this is a downcast point, and the calculation is continued
|
|
}
|
|
|
|
GccEnt_Position Qual1,Qual2;
|
|
if (cross < 0.) {
|
|
if (param3 > param4 ) {
|
|
if(Sens1 == Standard_True){
|
|
Qual1 = GccEnt_enclosed;
|
|
}
|
|
else {
|
|
Qual1 = GccEnt_outside;
|
|
}
|
|
}
|
|
else {
|
|
if(Sens1 == Standard_True){
|
|
Qual1 = GccEnt_outside;
|
|
}
|
|
else {
|
|
Qual1 = GccEnt_enclosed;
|
|
}
|
|
}
|
|
if (param1 > param2) {
|
|
if(Sens2 == Standard_True)
|
|
Qual2 = GccEnt_outside;
|
|
else
|
|
Qual2 = GccEnt_enclosed;
|
|
}
|
|
else {
|
|
if(Sens2 == Standard_True)
|
|
Qual2 = GccEnt_enclosed;
|
|
else
|
|
Qual2 = GccEnt_outside;
|
|
}
|
|
} // if (cross < 0 ...
|
|
else {
|
|
if (param3 > param4 ) {
|
|
if( Sens1 == Standard_True)
|
|
Qual1 = GccEnt_outside;
|
|
else
|
|
Qual1 = GccEnt_enclosed;
|
|
}
|
|
else {
|
|
if( Sens1 == Standard_True)
|
|
Qual1 = GccEnt_enclosed;
|
|
else
|
|
Qual1 = GccEnt_outside;
|
|
}
|
|
if (param1 > param2 ) {
|
|
if( Sens2 == Standard_True)
|
|
Qual2 = GccEnt_enclosed;
|
|
else
|
|
Qual2 = GccEnt_outside;
|
|
}
|
|
else {
|
|
if( Sens2 == Standard_True)
|
|
Qual2 = GccEnt_outside;
|
|
else
|
|
Qual2 = GccEnt_enclosed;
|
|
}
|
|
} // else ...
|
|
|
|
Standard_Real Tol = Precision::Confusion();
|
|
Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1),
|
|
Geom2dGcc_QualifiedCurve(basisC2,Qual2),
|
|
Radius, Tol);
|
|
if (!Fillet.IsDone() || Fillet.NbSolutions()==0) {
|
|
status = ChFi2d_ComputationError;
|
|
return filletEdge;
|
|
}
|
|
else if (Fillet.NbSolutions() >= 1) {
|
|
status = ChFi2d_IsDone;
|
|
Standard_Integer numsol = 1;
|
|
Standard_Integer nsol = 1;
|
|
TopoDS_Vertex Vertex1,Vertex2;
|
|
gp_Pnt2d Ptg1,Ptg2;
|
|
Standard_Real dist;
|
|
Standard_Real dist1 = 1.e40;
|
|
Standard_Boolean inside = Standard_False;
|
|
while (nsol<=Fillet.NbSolutions()) {
|
|
Fillet.Tangency1(nsol,PU1,PU2,Ptg1);
|
|
dist = Ptg1.Distance(p);
|
|
if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
|
|
inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1);
|
|
if ( inside && dist < dist1) {
|
|
numsol = nsol;
|
|
dist1 = dist;
|
|
} // if ((((inside && ...
|
|
} // if (C1->DynamicType( ...
|
|
else {
|
|
Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2);
|
|
dist = Ptg2.Distance(p);
|
|
inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3);
|
|
// case of arc of circle passing on the sewing
|
|
if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) &&
|
|
( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
|
|
// cas param3<param4
|
|
inside = (param3<PPU2 && PPU2<2*M_PI)
|
|
|| (0<=PPU2 && PPU2<param4-2*M_PI);
|
|
// cas param4<param3
|
|
inside = inside || (param4<PPU2 && PPU2<2*M_PI)
|
|
|| (0<=PPU2 && PPU2<param3-2*M_PI);
|
|
}
|
|
if ( inside && dist < dist1) {
|
|
numsol = nsol;
|
|
dist1 = dist;
|
|
} // if ((((param3 ...
|
|
} // else ...
|
|
nsol++;
|
|
} // while (nsol ...
|
|
gp_Circ2d cir(Fillet.ThisSolution(numsol));
|
|
Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir);
|
|
|
|
BRep_Builder B;
|
|
BRepAdaptor_Surface Adaptor3dSurface(refFace);
|
|
Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
|
|
Fillet.Tangency1(numsol,U1,U2,Ptg1);
|
|
Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2);
|
|
|
|
// check the validity of parameters
|
|
//// modified by jgv, 08.08.2011 for bug 0022695 ////
|
|
//inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1);
|
|
inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1);
|
|
/////////////////////////////////////////////////////
|
|
if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
|
|
&& ( (2*M_PI<param1 && 2*M_PI>param2) || (2*M_PI<param2 && 2*M_PI>param1) ) ) {
|
|
// arc of circle containing the circle origin
|
|
// case param1<param2
|
|
inside = (param1<U2 && U2<2*M_PI) || (0<=U2 && U2<param2-2*M_PI);
|
|
// case param2<param1
|
|
inside = inside || (param2<U2 && U2<2*M_PI) || (0<=U2 && U2<param1-2*M_PI);
|
|
}
|
|
if (!inside) {
|
|
status = ChFi2d_ComputationError;
|
|
return filletEdge;
|
|
}
|
|
|
|
//// modified by jgv, 08.08.2011 for bug 0022695 ////
|
|
//inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3);
|
|
inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3);
|
|
/////////////////////////////////////////////////////
|
|
if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
|
|
&& ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
|
|
// arc of circle containing the circle origin
|
|
// cas param3<param4
|
|
inside = (param3<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param4-2*M_PI);
|
|
// cas param4<param3
|
|
inside = inside || (param4<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param3-2*M_PI);
|
|
}
|
|
if (!inside) {
|
|
status = ChFi2d_ComputationError;
|
|
return filletEdge;
|
|
}
|
|
|
|
gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y());
|
|
gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y());
|
|
B.MakeVertex(Vertex1, p1,Tol);
|
|
NewExtr1 = Vertex1;
|
|
if (Abs(U2-ufirst1) <= Precision::PConfusion()) {
|
|
NewExtr1 = V1;
|
|
}
|
|
if (Abs(U2-ulast1) <= Precision::PConfusion()) {
|
|
NewExtr1 = V2;
|
|
}
|
|
|
|
B.MakeVertex(Vertex2, p2,Tol);
|
|
NewExtr2 = Vertex2;
|
|
if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) {
|
|
NewExtr2 = V3;
|
|
}
|
|
if (Abs(Vv2-ulast2) <= Precision::PConfusion()) {
|
|
NewExtr2 = V4;
|
|
}
|
|
|
|
//=======================================================================
|
|
// Update tops of the fillet. +
|
|
//=======================================================================
|
|
gp_Pnt Pntbid;
|
|
gp_Pnt2d sommet;
|
|
Pntbid = BRep_Tool::Pnt(V);
|
|
sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y());
|
|
|
|
gp_Pnt pntBid;
|
|
gp_Pnt2d somBid;
|
|
if (V1.IsSame(V)) {
|
|
pntBid = BRep_Tool::Pnt(V2);
|
|
somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
|
|
}
|
|
else {
|
|
pntBid = BRep_Tool::Pnt(V1);
|
|
somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
|
|
}
|
|
|
|
gp_Vec2d vec;
|
|
ElCLib::D1(U1,cir,Ptg1,vec);
|
|
|
|
gp_Vec2d vec1;
|
|
if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
|
|
Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
|
|
gp_Circ2d cir2d(CC1->Circ2d());
|
|
Standard_Real par = ElCLib::Parameter(cir2d,Ptg1);
|
|
gp_Pnt2d Pd;
|
|
ElCLib::D1(par,cir2d,Pd,vec1);
|
|
} // if (C1->DynamicType() ...
|
|
else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
|
|
Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
|
|
gp_Lin2d lin2d(CC1->Lin2d());
|
|
Standard_Real par = ElCLib::Parameter(lin2d,sommet);
|
|
vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y());
|
|
gp_Pnt2d Pd;
|
|
ElCLib::D1(par,lin2d,Pd,vec1);
|
|
} // else if ...
|
|
|
|
if (OE1 == TopAbs_REVERSED) {
|
|
vec1.Reverse();
|
|
} // if (OE1 ...
|
|
Standard_Real cross = vec1*vec;
|
|
Standard_Boolean Sense = cross > 0.;
|
|
if (U1 > Vv1 && U1 > 2.*M_PI) {
|
|
ElCLib::AdjustPeriodic(0.,2.*M_PI,Precision::Confusion(),U1,Vv1);
|
|
} // if (U1 ...
|
|
if (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD ||
|
|
O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED ) {
|
|
filletEdge = BRepLib_MakeEdge(circle, refSurf,
|
|
NewExtr1, NewExtr2, U1, Vv1);
|
|
} // if (O1 == ...
|
|
else {
|
|
filletEdge = BRepLib_MakeEdge(circle, refSurf,
|
|
NewExtr2, NewExtr1, Vv1, U1);
|
|
} // else ...
|
|
if (!Sense) {
|
|
TopAbs_Orientation S1 = filletEdge.Orientation();
|
|
if (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD ||
|
|
O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED ) {
|
|
filletEdge = BRepLib_MakeEdge(circle, refSurf,
|
|
NewExtr2, NewExtr1, Vv1, U1);
|
|
}
|
|
else {
|
|
filletEdge = BRepLib_MakeEdge(circle, refSurf,
|
|
NewExtr1, NewExtr2, U1, Vv1);
|
|
}
|
|
if (S1 == TopAbs_FORWARD) {
|
|
filletEdge.Orientation(TopAbs_REVERSED);
|
|
}
|
|
else {
|
|
filletEdge.Orientation(TopAbs_FORWARD);
|
|
}
|
|
} // if (!Sense
|
|
|
|
} // else if
|
|
|
|
BRepLib::BuildCurves3d(filletEdge);
|
|
return filletEdge;
|
|
} // BuildFilletEdge
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsAFillet
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const
|
|
{
|
|
Standard_Integer i = 1;
|
|
while (i <= fillets.Length()) {
|
|
const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i));
|
|
if (currentEdge.IsSame(E)) return Standard_True;
|
|
i++;
|
|
}
|
|
return Standard_False;
|
|
} // IsAFillet
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsAChamfer
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const
|
|
{
|
|
Standard_Integer i = 1;
|
|
while (i <= chamfers.Length()) {
|
|
const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i));
|
|
if (currentEdge.IsSame(E)) return Standard_True;
|
|
i++;
|
|
}
|
|
return Standard_False;
|
|
} // IsAChamfer
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsLineOrCircle
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
|
|
const TopoDS_Face& F)
|
|
{
|
|
Standard_Real first, last;
|
|
TopLoc_Location loc;
|
|
// syntaxe invalide sur NT
|
|
// const Handle(Geom2d_Curve)& C =
|
|
// BRep_Tool::CurveOnSurface(E,F,first,last);
|
|
Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
|
|
Handle(Geom2d_Curve) basisC;
|
|
Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
|
|
if (!TC.IsNull())
|
|
basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve());
|
|
else
|
|
basisC = Handle(Geom2d_Curve)::DownCast(C);
|
|
|
|
if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
|
|
|| basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
|
|
return Standard_True;
|
|
}
|
|
else {
|
|
return Standard_False;
|
|
} // else ...
|
|
} // IsLineOrCircle
|