How to merge two cylindrical faces?

I made a common boolean operation between a cylinder and a block, a result is obtained as shown in the attached file. But there is an edge on the cylindrical surface which I want to remove it. Any suggestion will be precious for me to resolve this problem?

Here is my code which is using.

// first Shape = Cylinder
gp_Pnt middlePoint = gp_Pnt(1000, 0, 0);
gp_Dir direction = gp_Dir(0, 1, 0);
gp_Ax2 Ax2 = gp_Ax2(middlePoint, direction);
aCylinderShape = BRepPrimAPI_MakeCylinder(Ax2, 1000,2000);

// second Shape = Cone
middlePoint = gp_Pnt(0, 0, 0);
direction = gp_Dir(1, 0, 0);
Ax2 = gp_Ax2(middlePoint, direction);
//Shape2 = BRepPrimAPI_MakeCone(Ax2, 0.0635114, 0, 0.309304);
aBoxShape = BRepPrimAPI_MakeBox(2000,1000,2000);

TopoDS_Shape aFuseShape = BRepAlgoAPI_Common(aCylinderShape, aBoxShape);

Attachments: 
George Feng's picture

Here is the image.

Attachments: 
George Feng's picture

In the result figure, the line I want to remove is a seam line which is very important for OCC and can not be removed. But there are some cases in which I want to merge two cylindrical surfaces. For example, there one edge generated by the following code I want to remove, which is shown in the attached figure.

TopoDS_Shape aCylinderShape, aBoxShape;

// first Shape = Cylinder
gp_Pnt middlePoint = gp_Pnt(500, 0, 1000);
gp_Dir direction = gp_Dir(0, 1, 0);
gp_Ax2 Ax2 = gp_Ax2(middlePoint, direction);
aCylinderShape = BRepPrimAPI_MakeCylinder(Ax2, 500,2000);

// second Shape = Cone
middlePoint = gp_Pnt(0, 0, 0);
direction = gp_Dir(1, 0, 0);
Ax2 = gp_Ax2(middlePoint, direction);
//Shape2 = BRepPrimAPI_MakeCone(Ax2, 0.0635114, 0, 0.309304);
aBoxShape = BRepPrimAPI_MakeBox(2000,1000,2000);

//TopoDS_Shape aFuseShape = BRepAlgoAPI_Fuse(aCylinderShape, aBoxShape);
//TopoDS_Shape aFuseShape = BRepAlgoAPI_Cut(aCylinderShape, aBoxShape);
TopoDS_Shape aFuseShape = BRepAlgoAPI_Common(aCylinderShape, aBoxShape);

Attachments: 
George Feng's picture

I have made a greate breakthrough about the problem by now. Here is the steps I have done.
(1) Find all the adjacent faces with the same type surfaces. These faces will be merged into one face in the latter steps. In the given example, they are two cylindrical faces.
(2) Find the boundary edges of the faces needed to be merged, and add them to a wire. This wire can be repaired with ShapeFix_Wire.
(3) Make a new face according to the repaired wire and the surface shared by all the faces to be merged. In this problem the surface is a cylinrical surface.
This step is complex and takes me three weeks to finish it, and now there is still some problems.
(3.a) After two faces are merged, some curves on each face are still not merged.
(3.b) After projecting the result shape which is a cylinrical surface here, an extra edge is appeared. I don't know why this happened and I have to move forward for this problem.

Anyway, now I can build a face according to a surface and a wire, which is a greate progress.

I will post part of my work here.

Attachments: 
George Feng's picture

TopoDS_Wire OccUtility::MakeWireWithEdges(CList &aEdgeList)
{
TopoDS_Edge aEdge;
BRepBuilderAPI_MakeWire aMakeWire;
Standard_Real tol = 0.01;
ShapeFix_ShapeTolerance FTol;

Handle(ShapeExtend_WireData) sbwd1 = new ShapeExtend_WireData();
POSITION pos = aEdgeList.GetHeadPosition();

while (pos)
{
aEdge = aEdgeList.GetNext(pos);
sbwd1->Add(aEdge);
}

Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
sfw->Load(sbwd1);
sfw->Perform();
//Reorder edges is very important
sfw->FixReorder();
sfw->SetMaxTolerance(tol);
///////////////////////////////////
sfw->ClosedWireMode() = Standard_True;
sfw->FixConnected(1.e-3);
sfw->FixClosed(1.e-3);

for (int i = 1; i <= sfw->NbEdges(); i ++)
{
TopoDS_Edge Edge = sfw->WireData()->Edge(i);
FTol.SetTolerance(Edge, tol, TopAbs_VERTEX);
aMakeWire.Add(Edge);
}

TopoDS_Wire aWire = aMakeWire.Wire();
return aWire;
}
TopoDS_Face OccUtility::RepairWire(Handle(Geom_Surface) S, TopoDS_Wire &aWire)
{

BRep_Builder B;
TopoDS_Wire W;
BRepTools_WireExplorer exEdge;
TopoDS_Edge aEdge, aEdge1, aEdge2;//
TopoDS_Vertex FirstV, LastV, V1, V2;

Standard_Real aTol;
Handle(Geom2d_Curve) theCurve2d_1, theCurve2d_2;
Handle(Geom_Surface) tSurface;
TopLoc_Location L;
Standard_Real First, Last;
Standard_Real First2d, Last2d;

TopTools_ListOfShape aEdgeList,aEdge1List;
TopAbs_Orientation aOrientation;

gp_Pnt aPnt1,aPnt2, aFirstPnt, aLastPnt;
Handle_Geom_Curve theCurve;

exEdge.Init(aWire);
aEdge1 = TopoDS::Edge(exEdge.Current());
V1 = exEdge.CurrentVertex();

TopoDS_Edge FirstEdge = aEdge1;
FirstV = V1;
int bLastEdge = 0;
int bMoreThan2Edges = 0;
int bClosed = 0;
int bExistClosed = 0;

if(exEdge.More())
{
exEdge.Next();
bMoreThan2Edges = 1;
}
// make the face
TopoDS_Face F;
B.MakeFace(F,S,Precision::Confusion());

// make the wire
B.MakeWire(W);

while(bMoreThan2Edges)
{
if(bLastEdge)
{
aEdge2 = FirstEdge;
V2 = FirstV;
}
else
{
aEdge2 = TopoDS::Edge(exEdge.Current());
// If you want to extract the Vertex belongs to Edge1, Edge2. use CurrentVertex() Method
V2 = exEdge.CurrentVertex();
}

if(aEdge2.IsNull()) continue;

aTol = BRep_Tool::Tolerance(aEdge1);

BRep_Tool::CurveOnSurface(aEdge1, theCurve2d_1, tSurface, L, First2d, Last2d);
theCurve = BRep_Tool::Curve(aEdge1, L, First, Last);;

//·ìºÏÏßSeam edge
bClosed = BRep_Tool::IsClosed(aEdge1, tSurface, L);

aEdge = TopoDS::Edge( GetEdgeInEdgeList(aEdge1, aEdgeList, aEdge1List) );

if(bClosed && !aEdge.IsNull())
{
aOrientation = aEdge.Orientation();
if(aOrientation == TopAbs_FORWARD)
{
aEdge.Orientation(TopAbs_REVERSED);//aEdge-Orientation
}
else if(aOrientation == TopAbs_REVERSED)
{
aEdge.Orientation(TopAbs_FORWARD);//aEdge-Orientation
}
bExistClosed = 1;
}
else
{
MakeEdge(aEdge1, F, FirstV, LastV, V1, V2,
aEdge);//MakeEdge
if(bClosed)
{
aEdge1List.Append(aEdge1);
aEdgeList.Append(aEdge);
bExistClosed = 1;
}
}

B.Add(W,aEdge);//aEdge-Added to a Wire

aEdge1 = aEdge2;
V1 = V2;

if (!bLastEdge)
{
exEdge.Next();
}

if(exEdge.More())
{
continue;
}
else if (bLastEdge==0)
{
bLastEdge = 1;
aEdge1 = aEdge2;
}
else
{
break;
}
}
B.Add(F,W);
//ÓÉÓÚÔÚʵÌåÔìÐÍÖв»»á´æÔÚÎÞÏÞ³¤µÄʵÌ壬ËùÒÔÔڴ˼ٶ¨ËùÓеÄWire¶¼ÊÇ·â±ÕµÄ
W.Closed(1);
//ÓÉÓÚÃæÊÇ·ñ±ÕºÏÊÇÖ±½Ó´ÓÆäËûÃæÉú³ÉµÄ£¬ËùÒÔÔڴ˶ÔÓڱպϵÄÃ涼ÔÚÐÂÉú³ÉµÄÃæÖÐÉèÖÃΪ±ÕºÏ
F.Closed(bExistClosed);
aWire = W;
return F;
}
TopoDS_Shape OccUtility::GetEdgeInEdgeList(TopoDS_Shape &tEdge, TopTools_ListOfShape &aEdgeList, TopTools_ListOfShape &aEdgeList1)
{
TopoDS_Shape aResShape;

TopTools_ListIteratorOfListOfShape itCheck;
TopTools_ListIteratorOfListOfShape itCheck1;

itCheck.Initialize(aEdgeList);
itCheck1.Initialize(aEdgeList1);

for (; itCheck1.More(); )
{
if ( itCheck1.Value().TShape() == tEdge.TShape())
{
aResShape = itCheck.Value();
return aResShape;
}

itCheck.Next();
itCheck1.Next();
}
return aResShape;
}
TopoDS_Shape OccUtility::SewFaces(TopoDS_Shape &aShape)
{
BRepBuilderAPI_Sewing aSewing;
TopExp_Explorer ExpFace;
TopoDS_Face aFace;
BRepBuilderAPI_MakeWire aWire;
Standard_Integer nFaceCount = 0;

for (ExpFace.Init(aFace, TopAbs_FACE); ExpFace.More(); ExpFace.Next())
{
aFace = TopoDS::Face(ExpFace.Current());
aSewing.Add(aFace);
nFaceCount++;
}
if(nFaceCount==0)return aShape;

aSewing.SetNonManifoldMode(true) ;
aSewing.Perform();
TopoDS_Shape swdShp = aSewing.SewedShape();

return swdShp;
}
Standard_Boolean OccUtility::IsShapeInShapeList(TopoDS_Shape &aShape, TopTools_ListOfShape &aShapeList)
{
TopTools_ListIteratorOfListOfShape itCheck;
for (itCheck.Initialize(aShapeList); itCheck.More(); itCheck.Next())
{
if (itCheck.Value() == aShape)
{
return Standard_True;
}
}
return Standard_False;
}
void OccUtility::MakeEdge(TopoDS_Edge &aEdge1, TopoDS_Face &F, TopoDS_Vertex &FirstV, TopoDS_Vertex &LastV, TopoDS_Vertex &V1,TopoDS_Vertex &V2,
TopoDS_Edge &aEdge)
{
BRep_Builder B;

gp_Pnt aPnt1,aPnt2, aFirstPnt, aLastPnt;

Standard_Real aTol;
Handle(Geom2d_Curve) theCurve2d_1, theCurve2d_2;
Handle(Geom_Surface) tSurface;
TopLoc_Location L;
Standard_Real First, Last;
Standard_Real First2d, Last2d;

Handle_Geom_Curve theCurve;

//Degenerated
int bDegenerated = 0;
bDegenerated = BRep_Tool::Degenerated(aEdge1);
if(bDegenerated)
{
B.MakeEdge(aEdge);
}
else
{
theCurve = BRep_Tool::Curve(aEdge1, L, First, Last);;
aTol = BRep_Tool::Tolerance(aEdge1);
B.MakeEdge(aEdge, theCurve, aTol);//aEdge-MakeEdge
}

BRep_Tool::CurveOnSurface(aEdge1, theCurve2d_1, tSurface, L, First2d, Last2d);

//Á½Ìõ¶þάÇúÏß
//ÏÂÃæµÄ´úÂëÀ´×ÔÓÚBRepTools_ShapeSet::AddGeometry, and BRep_Tool::CurveOnSurface
Standard_Boolean Eisreversed = (aEdge1.Orientation() == TopAbs_REVERSED);
BRep_ListIteratorOfListOfCurveRepresentation itrc((*((Handle(BRep_TEdge)*)&aEdge1.TShape()))->ChangeCurves());

//Must be exected only once for the following recycle.
while(itrc.More())
{
const Handle(BRep_CurveRepresentation)& cr = itrc.Value();
const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
GC->Range(First,Last);
if (cr->IsCurveOnSurface())
{
theCurve2d_1 = GC->PCurve();
//theCurve2d_1 = Handle(Geom2d_Curve)();

Handle(Geom_Surface) S = GC->Surface();

//Ö»ÓÐÊǵ±Ç°ÁÚ½ÓÃæÉϵı߲ÅÊÇÓÐÓõÄ
if(S == tSurface)
{
if (GC->IsCurveOnClosedSurface())
{
theCurve2d_2 = GC->PCurve2();
//theCurve2d_2 = Handle(Geom2d_Curve)();
B.UpdateEdge(aEdge, theCurve2d_1, theCurve2d_2, F, aTol);//aEdge-UpdateEdge
}
else
{
B.UpdateEdge(aEdge, theCurve2d_1, F, aTol);//aEdge-UpdateEdge
}
}
}

itrc.Next();
}

B.Degenerated(aEdge,bDegenerated);

//else if (myWithTriangles) // for XML Persistence
//{
// if (CR->IsPolygon3D())
// {
// if (!CR->Polygon3D().IsNull())
// {
// myPolygons3D.Add(CR->Polygon3D());
// ChangeLocations().Add(CR->Location());
// }
// }
// else if (CR->IsPolygonOnTriangulation())
// {
// myTriangulations.Add(CR->Triangulation());
// myNodes.Add(CR->PolygonOnTriangulation());
// ChangeLocations().Add(CR->Location());
// if (CR->IsPolygonOnClosedTriangulation())
// myNodes.Add(CR->PolygonOnTriangulation2());
// }
// else if (CR->IsPolygonOnSurface())
// {
// mySurfaces.Add(CR->Surface());
// myPolygons2D.Add(CR->Polygon());
// ChangeLocations().Add(CR->Location());
// if (CR->IsPolygonOnClosedSurface())
// myPolygons2D.Add(CR->Polygon2());
// }
//}

aPnt1 = BRep_Tool::Pnt(V1);
aPnt2 = BRep_Tool::Pnt(V2);

FirstV = TopExp::FirstVertex(aEdge1);
LastV = TopExp::LastVertex(aEdge1);

//¶¥µãÖоßÓнÏСµÄ²ÎÊýÖµÆäÖ¸ÏòΪÕý·½Ïò£¬·ñÔòΪ·´·½Ïò
FirstV.Orientation(TopAbs_FORWARD);
LastV.Orientation(TopAbs_REVERSED);

B.Add(aEdge,FirstV);//aEdge-Add vertex to edge
B.Add(aEdge,LastV);//aEdge-Add vertex to edge

B.Range(aEdge, First, Last);//aEdge-Range

B.SameRange(aEdge, Standard_True);//aEdge-Range
B.SameParameter(aEdge, Standard_True);//aEdge-Range

aFirstPnt = BRep_Tool::Pnt(FirstV);;
aLastPnt = BRep_Tool::Pnt(LastV);

if( aPnt1.Distance(aFirstPnt)<1.0e-6 && aPnt2.Distance(aLastPnt)<1.0e-6 )
{
//±ßµÄ³¯ÏòÓ뵱ǰ¹¹Ôì»·µÄ·½ÏòÊÇ·ñÏàͬ£¬ÏàͬΪÕý£¬·ñÔòΪ¸º
aEdge.Orientation(TopAbs_FORWARD);//aEdge-Orientation
}
else if( aPnt1.Distance(aLastPnt)<1.0e-6 && aPnt2.Distance(aFirstPnt)<1.0e-6 )
{
aEdge.Orientation(TopAbs_REVERSED);//aEdge-Orientation
}

}