tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.27k stars 364 forks source link

Convert topoDS Face to GeomSurface with BRep_Tool.Surface returns unexpected result #1340

Open Squirrel8475 opened 1 month ago

Squirrel8475 commented 1 month ago

Hello,

Here what I am trying to do: first a Geom_Surface is split by an edge using BOPAlgo_Splitter. One of the resulting topoDS_Face shall be converted to Geom_Surface with the help of BRep_Tool.Surface.

Any idea?

Have a nice day.

# -*- coding: utf-8 -*-
from OCC.Core.BOPAlgo import BOPAlgo_Splitter
from OCC.Core.gp import gp_Pnt
from OCC.Extend.TopologyUtils import TopologyExplorer
from OCC.Core.BRep import BRep_Tool
from OCC.Display.WebGl.jupyter_renderer import JupyterRenderer
from OCC.Core.BRepBuilderAPI import (BRepBuilderAPI_MakeVertex,BRepBuilderAPI_MakeEdge,BRepBuilderAPI_MakeFace,BRepBuilderAPI_MakeWire)

coords=[
    (-20, -20, 0),
    (-20,20, 0),
    (20,20, 0),
    (20,-20, 0)    
]
# Create vertices
vertices=list()
for coord in coords:
    vertices.append( BRepBuilderAPI_MakeVertex(gp_Pnt(*coord)).Shape() )
# Join vertices to create a closed loop of edges
nv=len(vertices)
edges=list()
for i in range(0,nv,1):
    if i<nv-1:
        edge=BRepBuilderAPI_MakeEdge(vertices[i],vertices[i+1]).Shape()
    elif i==nv-1:
        edge=BRepBuilderAPI_MakeEdge(vertices[i],vertices[0]).Shape()
    else:
        raise ValueError('Out of bounds, i=',i)
    edges.append(edge)
a_maker = BRepBuilderAPI_MakeWire()
for edge in edges:
    a_maker.Add(edge)
a_maker.Build()
original_topods_wire=a_maker.Shape()
OnlyPlane = True
a_maker = BRepBuilderAPI_MakeFace(original_topods_wire,OnlyPlane)
a_maker.Build()
a_topods_face = a_maker.Shape()

# Create an edge based on two points
p1 = gp_Pnt(0, -20, 0)
p2 = gp_Pnt(0,20, 0)
a_topods_edge = BRepBuilderAPI_MakeEdge(p1, p2).Edge()

# Split the geom face face by edge
splitter = BOPAlgo_Splitter()
splitter.AddArgument(a_topods_face)
splitter.AddTool(a_topods_edge)
splitter.Perform()

# Get one of the resulting topods face - works fine
faces = TopologyExplorer(splitter.Shape()).faces()
my_renderer = JupyterRenderer()
for face in faces:
    a_topods_split_face=face
my_renderer.DisplayShape(a_topods_split_face, update=True) 

# Convert the trimmed topods face to  geom surface 
a_geom_surface_after_conversion = BRep_Tool.Surface(a_topods_split_face) 
check_the_face = BRepBuilderAPI_MakeFace(a_geom_surface_after_conversion,1e-6).Face()
print(check_the_face)
my_renderer = JupyterRenderer()
my_renderer.DisplayShape(check_the_face, update=True)   # nothing displayed
tpaviot commented 4 weeks ago

I dont understand the workflow: you need to convert a topods_face to a geom_surface and then back to a topods_face?

Squirrel8475 commented 4 weeks ago

The code was an attempt to illustrate the problem, indeed not reflecting the work flow.

The work flow is as follow: two independant apps are running. -The first handles Bezier geom surface and trim them, delivering toposds faces. It was meant to be a standalone app and stop there.

-The second app works with geom surfaces. It was not suppose initially to deal with toposds faces.

So there is a need to make the bridge between the two, which explains why to convert from toposds face to geom surface. The only reason why the surface is then converted to toposds face again was to visualise in the jupyterlab renderer.

Squirrel8475 commented 3 weeks ago

In case additionnal details are needed, please let me know @tpaviot

Squirrel8475 commented 1 week ago

So far I could not find how to go from a trimmed BSpline surface to topods face, and then convert it back to a geom surface without losing the trimming information;

After some more researches, I found more info here:

https://stackoverflow.com/questions/75917206/how-to-convert-geom-bsplinesurface-to-a-topods-shape-or-face-after-some-local-mo

The basic issue is that you are creating new Face without any bounds - you have to reuse Wires and Edges of original Face and create new ones adopted to new surface. This means that you'll have to manually re-create 2D curves on Edges within new UV surface range or use some tool re-projecting 3D curve onto new surface to create P-curves, and then make new Face with these new Wires + new surface

It is not possible in my case, the geometries are too complicated.

The only way to move forward would be to find a way to trim the GeomSurface (by another surface) without using the TopoDS tools. It would eliminate the need to convert it back afterwards. Anyone knows how to do that?