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

Reply via email to