def test_curve_adaptor(self):
     # related to issue #1057 https://github.com/tpaviot/pythonocc-core/issues/1057
     p1 = gp_Pnt(5, -5, 0)
     p2 = gp_Pnt(5, 5, 0)
     ed1 = BRepBuilderAPI_MakeEdge(p2, p1).Edge()
     c1 = BRepAdaptor_Curve(ed1)
     self.assertTrue(isinstance(c1.Curve(), GeomAdaptor_Curve))
     # should pass on all platforms
     self.assertTrue(isinstance(c1.Curve().Curve(), Geom_Curve))
     c2 = BRepAdaptor_Curve(ed1).Curve()
     # only works on linux
     if sys.platform == "linux":
         self.assertTrue(isinstance(c2.Curve(), Geom_Curve))
         self.assertTrue(
             isinstance(BRepAdaptor_Curve(ed1).Curve().Curve(), Geom_Curve))
Esempio n. 2
0
def project_mesh_to_cad_2d(mesh, cad):

    from OCC.Core.BRepAdaptor import BRepAdaptor_Curve
    from OCC.Core.gp import gp_Pnt
    from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnCurve

    coorddata = mesh.coordinates.dat.data
    ids = mesh.exterior_facets.unique_markers

    filt = lambda arr: arr[numpy.where(arr < mesh.coordinates.dof_dset.size)[0]]
    boundary_nodes = {id: filt(mesh.coordinates.function_space().boundary_nodes(int(id))) for id in ids}

    for (id, edge) in zip(ids, cad.edges()):
        owned_nodes = boundary_nodes[id]
        for other_id in ids:
            if id == other_id:
                continue
            owned_nodes = numpy.setdiff1d(owned_nodes, boundary_nodes[other_id])

        curve = BRepAdaptor_Curve(edge)

        for node in owned_nodes:
            pt = gp_Pnt(*coorddata[node, :], 0)
            proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve())
            if proj.NbPoints() > 0:
                projpt = proj.NearestPoint()
                coorddata[node, :] = projpt.Coord()[0:2]
            else:
                warnings.warn("Projection of point %s onto curve failed" % coorddata[node, :])
Esempio n. 3
0
def trimedge(lbound, ubound, occedge):
    """
    This function trims the OCCedge according to the specified lower and upper bound.
 
    Parameters
    ----------
    lbound : float
        The lower bound of the OCCedge.
        
    ubound : float
        The upper bound of the OCCedge.
        
    occedge : OCCedge
        The edge to be trimmed.

    Returns
    -------
    trimmed edge : OCCedge
        The trimmed OCCedge.
    """
    adaptor = BRepAdaptor_Curve(occedge)
    tr = Geom_TrimmedCurve(adaptor.Curve().Curve(), lbound, ubound)
    tr.SetTrim(lbound, ubound)
    bspline_handle = geomconvert_CurveToBSplineCurve(tr.BasisCurve())
    tr_edge = BRepBuilderAPI_MakeEdge(bspline_handle)

    return tr_edge.Edge()
Esempio n. 4
0
def other():
    for (id, edge) in zip(ids, cad.edges()):
        owned_nodes = boundary_nodes[id]
        for other_id in ids:
            if id == other_id:
                continue
            owned_nodes = numpy.setdiff1d(owned_nodes,
                                          boundary_nodes[other_id])

        curve = BRepAdaptor_Curve(edge)

        for node in owned_nodes:
            pt = gp_Pnt(*coorddata[node, :], 0)
            proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve())
            if proj.NbPoints() > 0:
                projpt = proj.NearestPoint()
                coorddata[node, :] = projpt.Coord()[0:2]
            else:
                warnings.warn("Projection of point %s onto curve failed" %
                              coorddata[node, :])
Esempio n. 5
0
def project_mesh_to_cad_2d(mesh, cad):

    from OCC.Core.BRepAdaptor import BRepAdaptor_Curve
    from OCC.Core.gp import gp_Pnt
    from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnCurve

    coorddata = mesh.coordinates.dat.data
    ids = mesh.exterior_facets.unique_markers

    filt = lambda arr: arr[numpy.where(arr < mesh.coordinates.dof_dset.size)[0]
                           ]
    boundary_nodes = {
        id: filt(mesh.coordinates.function_space().boundary_nodes(
            int(id), "topological"))
        for id in ids
    }

    for id_ in ids:
        for node in boundary_nodes[id_]:
            #print(node)
            coords = coorddata[node, :]
            best_coords = coords
            dist_old = np.inf
            for edge in cad.edges():
                curve = BRepAdaptor_Curve(edge)
                pt = gp_Pnt(*coorddata[node, :], 0)
                proj = GeomAPI_ProjectPointOnCurve(pt, curve.Curve().Curve())
                if proj.NbPoints() > 0:
                    projpt = proj.NearestPoint()
                    projected_coords = np.array(projpt.Coord()[0:2])
                    dist = np.linalg.norm(coords - projected_coords)
                    if dist_old > dist:
                        best_coords = projected_coords
                        dist_old = dist

                    #print(coords, projected_coords, np.linalg.norm(coords-projected_coords))
            #print(distances)
            coorddata[node, :] = best_coords
    return
Esempio n. 6
0
 def describe_edge(self, edge):
     curve_adaptor = BRepAdaptor_Curve(edge)
     first = curve_adaptor.FirstParameter()
     last = curve_adaptor.LastParameter()
     geom_curve = curve_adaptor.Curve()
     if (geom_curve.GetType() == GeomAbs_Line):
         return "Is line"
     elif (geom_curve.GetType() == GeomAbs_Circle):
         return "Is circle"
     elif (geom_curve.GetType() == GeomAbs_Ellipse):
         return "Is ellipse"
     elif (geom_curve.GetType() == GeomAbs_Hyperbola):
         return "Is hyperbola"
     elif (geom_curve.GetType() == GeomAbs_Parabola):
         return "Is parabola"
     elif (geom_curve.GetType() == GeomAbs_BezierCurve):
         return "Is bezier"
     elif (geom_curve.GetType() == GeomAbs_BSplineCurve):
         return "Is bspline"
     elif (geom_curve.GetType() == GeomAbs_OffsetCurve):
         return "Is offset"
     elif (geom_curve.GetType() == GeomAbs_OtherCurve):
         return "Is other"
Esempio n. 7
0
class Edge(TopoDS_Edge, BaseObject):
    def __init__(self, edge):
        assert isinstance(edge, TopoDS_Edge), 'need a TopoDS_Edge, got a %s' % edge.__class__
        assert not edge.IsNull()
        super(Edge, self).__init__()
        BaseObject.__init__(self, 'edge')
        # we need to copy the base shape using the following three
        # lines
        assert self.IsNull()
        self.TShape(edge.TShape())
        self.Location(edge.Location())
        self.Orientation(edge.Orientation())
        assert not self.IsNull()

        # tracking state
        self._local_properties_init = False
        self._curvature_init = False
        self._geometry_lookup_init = False
        self._curve_handle = None
        self._curve = None
        self._adaptor = None
        self._adaptor_handle = None

        # instantiating cooperative classes
        # cooperative classes are distinct through CamelCaps from
        # normal method -> pep8
        self.DiffGeom = DiffGeomCurve(self)
        self.Intersect = IntersectCurve(self)
        self.Construct = ConstructFromCurve(self)

        # GeomLProp object
        self._curvature = None

    def is_closed(self):
        return self.adaptor.IsClosed()

    def is_periodic(self):
        return self.adaptor.IsPeriodic()

    def is_rational(self):
        return self.adaptor.IsRational()

    def continuity(self):
        return self.adaptor.Continuity

    def degree(self):
        if 'line' in self.type:
            return 1
        elif 'curve' in self.type:
            return self.adaptor.Degree()
        else:
            # hyperbola, parabola, circle
            return 2

    def nb_knots(self):
        return self.adaptor.NbKnots()

    def nb_poles(self):
        return self.adaptor.NbPoles()

    @property
    def curve(self):
        if self._curve is not None and not self.is_dirty:
            pass
        else:
            self._curve_handle = BRep_Tool().Curve(self)[0]
            self._curve = self._curve_handle#.GetObject()
        return self._curve

    @property
    def curve_handle(self):
        self.curve

        if self._curve_handle is not None and not self.is_dirty:
            return self._curve_handle
        else:
            return None

    @property
    def adaptor(self):
        if self._adaptor is not None and not self.is_dirty:
            pass
        else:
            self._adaptor = BRepAdaptor_Curve(self)
            self._adaptor_handle = BRepAdaptor_HCurve(self._adaptor)
        return self._adaptor

    @property
    def adaptor_handle(self):
        if self._adaptor_handle is not None and not self.is_dirty:
            pass
        else:
            self.adaptor
        return self._adaptor_handle

    @property
    def geom_curve_handle(self):
        """
        :return: Handle_Geom_Curve adapted from `self`
        """
        if self._adaptor_handle is not None and not self.is_dirty:
            return self._adaptor.Curve().Curve()
        else:
            return None

    @property
    def type(self):
        return geom_lut[self.adaptor.Curve().GetType()]

    def pcurve(self, face):
        """
        computes the 2d parametric spline that lies on the surface of the face
        :return: Geom2d_Curve, u, v
        """
        crv, u, v = BRep_Tool().CurveOnSurface(self, face)
        return crv.GetObject(), u, v

    def _local_properties(self):
        self._lprops_curve_tool = GeomLProp_CurveTool()
        self._local_properties_init = True

    def domain(self):
        '''returns the u,v domain of the curve'''
        return self.adaptor.FirstParameter(), self.adaptor.LastParameter()

#===========================================================================
#    Curve.GlobalProperties
#===========================================================================

    def length(self, lbound=None, ubound=None, tolerance=1e-5):
        '''returns the curve length
        if either lbound | ubound | both are given, than the length
        of the curve will be measured over that interval
        '''
        _min, _max = self.domain()
        if _min < self.adaptor.FirstParameter():
            raise ValueError('the lbound argument is lower than the first parameter of the curve: %s ' % (self.adaptor.FirstParameter()))
        if _max > self.adaptor.LastParameter():
            raise ValueError('the ubound argument is greater than the last parameter of the curve: %s ' % (self.adaptor.LastParameter()))

        lbound = _min if lbound is None else lbound
        ubound = _max if ubound is None else ubound
        return GCPnts_AbscissaPoint().Length(self.adaptor, lbound, ubound, tolerance)

#===========================================================================
#    Curve.modify
#===========================================================================

    def trim(self, lbound, ubound):
        '''
        trim the curve
        @param lbound:
        @param ubound:
        '''
        a, b = sorted([lbound, ubound])
        tr = Geom_TrimmedCurve(self.adaptor.Curve().Curve(), a, b).GetHandle()
        return Edge(make_edge(tr))

    def extend_by_point(self, pnt, degree=3, beginning=True):
        '''extends the curve to point

        does not extend if the degree of self.curve > 3
        @param pnt:
        @param degree:
        @param beginning:
        '''
        if self.degree > 3:
            raise ValueError('to extend you self.curve should be <= 3, is %s' % (self.degree))
        return geomlib.ExtendCurveToPoint(self.curve, pnt, degree, beginning)

#===========================================================================
#    Curve.
#===========================================================================
    def closest(self, other):
        return minimum_distance(self, other)

    def project_vertex(self, pnt_or_vertex):
        ''' returns the closest orthogonal project on `pnt` on edge
        '''
        if isinstance(pnt_or_vertex, TopoDS_Vertex):
            pnt_or_vertex = vertex2pnt(pnt_or_vertex)
            
        poc = GeomAPI_ProjectPointOnCurve(pnt_or_vertex, self.curve_handle)
        return poc.LowerDistanceParameter(), poc.NearestPoint()

    def distance_on_curve(self, distance, close_parameter, estimate_parameter):
        '''returns the parameter if there is a parameter
        on the curve with a distance length from u
        raises OutOfBoundary if no such parameter exists
        '''
        gcpa = GCPnts_AbscissaPoint(self.adaptor, distance, close_parameter, estimate_parameter, 1e-5)
        with assert_isdone(gcpa, 'couldnt compute distance on curve'):
            return gcpa.Parameter()

    def mid_point(self):
        """
        :return: the parameter at the mid point of the curve, and
        its corresponding gp_Pnt
        """
        _min, _max = self.domain()
        _mid = (_min+_max) / 2.
        return _mid, self.adaptor.Value(_mid)

    def divide_by_number_of_points(self, n_pts, lbound=None, ubound=None):
        '''returns a nested list of parameters and points on the edge
        at the requested interval [(param, gp_Pnt),...]
        '''
        _lbound, _ubound = self.domain()
        if lbound:
            _lbound = lbound
        elif ubound:
            _ubound = ubound

        # minimally two points or a Standard_ConstructionError is raised
        if n_pts <= 1:
            n_pts = 2

        try:
            npts = GCPnts_UniformAbscissa(self.adaptor, n_pts, _lbound, _ubound)
        except:
            print("Warning : GCPnts_UniformAbscissa failed")
        if npts.IsDone():
            tmp = []
            for i in xrange(1, npts.NbPoints()+1):
                param = npts.Parameter(i)
                pnt = self.adaptor.Value(param)
                tmp.append((param, pnt))
            return tmp
        else:
            return None

    def __eq__(self, other):
        if hasattr(other, 'topo'):
            return self.IsEqual(other)
        else:
            return self.IsEqual(other)

    def __ne__(self, other):
        return not self.__eq__(other)

    def first_vertex(self):
        return topexp.FirstVertex(self)

    def last_vertex(self):
        return topexp.LastVertex(self)

    def common_vertex(self, edge):
        vert = TopoDS_Vertex()
        if topexp.CommonVertex(self, edge, vert):
            return vert
        else:
            return False

    def as_vec(self):
        if self.is_line():
            first, last = map(vertex2pnt, [self.first_vertex(), self.last_vertex()])
            return gp_Vec(first, last)
        else:
            raise ValueError("edge is not a line, hence no meaningful vector can be returned")

#===========================================================================
#    Curve.
#===========================================================================

    def parameter_to_point(self, u):
        '''returns the coordinate at parameter u
        '''
        return self.adaptor.Value(u)

    def fix_continuity(self, continuity):
        """
        splits an edge to achieve a level of continuity
        :param continuity: GeomAbs_C*
        """
        return fix_continuity(self, continuity)

    def continuity_from_faces(self, f1, f2):
        return BRep_Tool_Continuity(self, f1, f2)

#===========================================================================
#    Curve.
#===========================================================================

    def is_line(self):
        '''checks if the curve is planar
        '''
        if self.nb_knots() == 2 and self.nb_poles() == 2:
            return True
        else:
            return False

    def is_seam(self, face):
        """
        :return: True if the edge has two pcurves on one surface
        ( in the case of a sphere for example... )
        """
        sae = ShapeAnalysis_Edge()
        return sae.IsSeam(self, face)

    def is_edge_on_face(self, face):
        '''checks whether curve lies on a surface or a face
        '''
        return ShapeAnalysis_Edge().HasPCurve(self, face)

#===========================================================================
#    Curve.graphic
#===========================================================================
    def show(self):
        '''
        poles, knots, should render all slightly different.
        here's how...

        http://www.opencascade.org/org/forum/thread_1125/
        '''
        super(Edge, self).show()
Esempio n. 8
0
def project_mesh_to_cad_3d(mesh, cad):

    from OCC.Core.BRepAdaptor import BRepAdaptor_Surface, BRepAdaptor_Curve
    from OCC.Core.gp import gp_Pnt
    from OCC.Core.GeomAPI import GeomAPI_ProjectPointOnSurf, GeomAPI_ProjectPointOnCurve

    coorddata = mesh.coordinates.dat.data
    ids = mesh.exterior_facets.unique_markers

    filt = lambda arr: arr[numpy.where(arr < mesh.coordinates.dof_dset.size)[0]
                           ]
    boundary_nodes = {
        id: filt(mesh.coordinates.function_space().boundary_nodes(
            int(id), "topological"))
        for id in ids
    }

    for (id, face) in zip(ids, cad.faces()):
        owned_nodes = boundary_nodes[id]
        for other_id in ids:
            if id == other_id:
                continue
            owned_nodes = numpy.setdiff1d(owned_nodes,
                                          boundary_nodes[other_id])

        surf = BRepAdaptor_Surface(face)

        for node in owned_nodes:
            pt = gp_Pnt(*coorddata[node, :])

            proj = GeomAPI_ProjectPointOnSurf(pt, surf.Surface().Surface())
            if proj.NbPoints() > 0:
                projpt = proj.NearestPoint()
                coorddata[node, :] = projpt.Coord()
            else:
                warnings.warn("Projection of point %s onto face %d failed" %
                              (coorddata[node, :], id))

        edges = set(cad.edges_from_face(face))

        for (other_id, other_face) in zip(ids, cad.faces()):
            if other_id <= id:
                continue

            intersecting_nodes = numpy.intersect1d(boundary_nodes[id],
                                                   boundary_nodes[other_id])
            if len(intersecting_nodes) == 0:
                continue

            other_edges = set(cad.edges_from_face(other_face))

            intersecting_edges = []
            for edge in edges:
                s = str(
                    edge
                )  # FIXME: is there a more elegant way to get the OCC id?
                for other_edge in other_edges:
                    other_s = str(other_edge)
                    if s == other_s:
                        intersecting_edges.append(edge)

            if len(intersecting_edges) == 0:
                warnings.warn(
                    "face: %s other_face: %s intersecting_edges: %s" %
                    (face, other_face, intersecting_edges))
                warnings.warn(
                    "Warning: no intersecting edges in CAD, even though vertices on both faces?"
                )
                continue

            for node in intersecting_nodes:
                pt = gp_Pnt(*coorddata[node, :])

                projections = []
                for edge in intersecting_edges:
                    curve = BRepAdaptor_Curve(edge)

                    proj = GeomAPI_ProjectPointOnCurve(pt,
                                                       curve.Curve().Curve())
                    if proj.NbPoints() > 0:
                        projpt = proj.NearestPoint()
                        sqdist = projpt.SquareDistance(pt)
                        projections.append((projpt, sqdist))
                    else:
                        warnings.warn(
                            "Projection of point %s onto curve failed" %
                            coorddata[node, :])

                (projpt, sqdist) = min(projections, key=lambda x: x[1])
                coorddata[node, :] = projpt.Coord()
Esempio n. 9
0
    def Write(self, path):
        from bcad.binterpreter.scl_context import SCLProjection
        p = SCLProjection(None)
        p.hlr_project(self.shapes)
        shapes = []
        for c in p.children:
            if c.shape != None:
                dump_topology_to_string(c.shape.get_shape())
                shapes.append(c.shape.get_shape())
        lines = []
        for s in shapes:
            lines.extend(self.collect_dumpable_shapes(s))
        #debug("Lines: %s"%(str(lines),))
        ctr = 0

        for l in lines:
            #debug ("l: %s"%(str(l),))
            if len(l)>1:
                s = l[0][:2]
                for p in l[1:]:
                    e = p[:2]
                    self.msp.add_line(s, e)
                    s = e
            # e = l[1][:2]
            # 
        self.doc.saveas(path)
        return
        
        for s in shapes:
            exp = TopExp_Explorer()
            exp.Init(s, TopAbs_EDGE)
            while exp.More():
                edge = exp.Value()
                if not is_edge(edge):
                    warning("Is not an edge.")
                if exp.Value().IsNull():
                    warning("TopoDS_Edge is null")

                curve_adaptor = BRepAdaptor_Curve(edge)
                first = curve_adaptor.FirstParameter()
                last = curve_adaptor.LastParameter()
                geom_curve = curve_adaptor.Curve()
                #edges.append(exp.Current())
                # first = topexp.FirstVertex(exp.Value())
                # last  = topexp.LastVertex(exp.Value())
                
                # # Take geometrical information from vertices.
                # pnt_first = BRep_Tool.Pnt(first)
                # pnt_last = BRep_Tool.Pnt(last)

                # a, b = BRep_Tool.Curve(exp.Value())
                exp.Next()
                if (geom_curve.GetType() == GeomAbs_Line):
                    debug("Is line")
                elif (geom_curve.GetType() == GeomAbs_Circle):
                    debug("Is circle")
                elif (geom_curve.GetType() == GeomAbs_Ellipse):
                    debug("Is ellipse")
                elif (geom_curve.GetType() == GeomAbs_Hyperbola):
                    debug("Is hyperbola")
                elif (geom_curve.GetType() == GeomAbs_Parabola):
                    debug("Is parabola")
                elif (geom_curve.GetType() == GeomAbs_BezierCurve):
                    debug("Is bezier")
                elif (geom_curve.GetType() == GeomAbs_BSplineCurve):
                    debug("Is bspline")
                elif (geom_curve.GetType() == GeomAbs_OffsetCurve):
                    debug("Is offset")
                elif (geom_curve.GetType() == GeomAbs_OtherCurve):
                    #debug("Is other")
                    continue
                    #self.msp.add_line()

                pts = discretize_edge(edge)
                debug("Curve[%i]: %s / %s"%(ctr, str(geom_curve.GetType()),str(edge)))
                ctr+=1