Hi,
I've updated my GeomPlate example to something a little more
interesting.
In the script below, a surface is not just constrained to a polygon,
and a point, but also to a radius.
scipy.optimize.fsolve takes care of the latter.
Cheers,
-jelle
from OCC.gp import *
from OCC.BRepBuilderAPI import *
from OCC.BRepPrimAPI import *
from OCC.GeomPlate import *
from OCC.Utils.Topology import WireExplorer, TopoDS
from OCC.BRepAdaptor import *
from OCC.BRepFill import *
from OCC.Extrema import *
from OCC import TopoDS
from OCC.GeomAdaptor import *
from OCC.GeomLProp import *
from OCC.GeomAPI import *
from OCC.BRep import *
from scipy.optimize import *
from OCC.ShapeAnalysis import *
import types
import scipy
from examples_gui import display, loop
import time
def build_plate(polygon, points):
'''
build a surface from a constraining polygon(s) and point(s)
@param polygon: list of polygons ( TopoDS_Shape)
@param points: list of points ( gp_Pnt )
'''
# plate surface
bpSrf = GeomPlate_BuildPlateSurface(3,15,2)
# add curve constraints
for poly in polygon:
for edg in WireExplorer(poly.Wire()).ordered_edges():
c = BRepAdaptor_HCurve()
c.ChangeCurve().Initialize(edg)
constraint = BRepFill_CurveConstraint(c.GetHandle(), 0)
bpSrf.Add(constraint.GetHandle())
# add point constraint
for pt in points:
bpSrf.Add(GeomPlate_PointConstraint(pt, 0).GetHandle())
bpSrf.Perform()
maxSeg, maxDeg, critOrder = 9,8,0
tol = 1e-4
dmax = max([tol,10*bpSrf.G0Error()])
srf = bpSrf.Surface()
plate = GeomPlate_MakeApprox(srf, tol, maxSeg, maxDeg, dmax,
critOrder)
uMin, uMax, vMin, vMax = srf.GetObject().Bounds()
face = BRepBuilderAPI_MakeFace(plate.Surface(), uMin, uMax, vMin,
vMax)
face.Build()
return TopoDS.TopoDS().Face(face.Shape())
def radius_at_uv(face, u, v):
'''
returns the mean radius at a u,v coordinate
@param face: surface input
@param u,v: u,v coordinate
'''
h_srf = BRep_Tool().Surface(face)
uv_domain = GeomLProp_SurfaceTool().Bounds(h_srf)
curvature = GeomLProp_SLProps(h_srf, u, v, 1, 1e-6)
try:
_crv_min = 1./curvature.MinCurvature()
except ZeroDivisionError:
_crv_min = 0.
try:
_crv_max = 1./curvature.MaxCurvature()
except ZeroDivisionError:
_crv_max = 0.
return abs((_crv_min+_crv_max)/2.)
def uv_from_projected_point_on_face(face, pt):
'''
returns the uv coordinate from a projected point on a face
'''
srf = BRep_Tool().Surface(face)
sas = ShapeAnalysis_Surface(srf)
uv = sas.ValueOfUV(pt, 1e-2)
print 'distance',sas.Value(uv).Distance(pt)
return uv.Coord()
class RadiusConstrainedSurface():
'''
returns a surface that has `radius` at `pt`
'''
def __init__(self, display, poly, pnt, targetRadius):
self.targetRadius = targetRadius
self.poly = poly
self.pnt = pnt
self.plate = self.build_surface()
def build_surface(self):
'''
builds and renders the plate
'''
self.plate = build_plate([self.poly], [self.pnt])
display.EraseAll()
display.DisplayShape(self.plate)
display.DisplayShape(self.poly.Shape())
vert = BRepBuilderAPI_MakeVertex(self.pnt)
display.DisplayShape(vert.Shape())
def radius(self, z):
'''
sets the height of the point constraining the plate, returns
the radius at this point
'''
if isinstance(z, types.FloatType):
self.pnt.SetX(z)
else:
self.pnt.SetX(z[0])
self.build_surface()
uv = uv_from_projected_point_on_face(self.plate, self.pnt)
radius = radius_at_uv(self.plate, uv[0], uv[1])
print 'z:',z, 'radius:', radius
self.curr_radius = radius
return self.targetRadius-abs(radius)
p1,p2,p3,p4,p5 =
gp_Pnt
(0,0,0),gp_Pnt(0,10,0),gp_Pnt(0,10,10),gp_Pnt(0,0,10),gp_Pnt(5,5,5)
poly = BRepBuilderAPI_MakePolygon()
map(poly.Add, [p1,p2,p3,p4,p1])
poly.Build()
for i in scipy.arange(1.,3.,0.2).tolist():
rcs = RadiusConstrainedSurface(display, poly, p5, i )
x = fsolve(rcs.radius, 1, maxfev=10000 )
print 'Goal: %s radius: %s' % ( i, rcs.curr_radius )
time.sleep(0.5)
loop()
_______________________________________________
Pythonocc-users mailing list
Pythonocc-users@gna.org
https://mail.gna.org/listinfo/pythonocc-users