def update_shape(self, change=None): d = self.declaration edges = TopTools_ListOfShape() wires = [] for c in self.children(): if not isinstance(c, OccShape): continue if c.shape is None: raise ValueError("Cannot build wire from empty shape: %s" % c) self.extract_edges(c, edges) else: for edge in d.edges: if isinstance(edge, TopoDS_Edge): edges.Append(edge) else: wires.append(edge) builder = BRepBuilderAPI_MakeWire() builder.Add(edges) for w in wires: builder.Add(w) if not builder.IsDone(): log.warning('Edges must be connected %s' % d) wire = builder.Wire() if d.reverse: wire.Reverse() self.curve = BRepAdaptor_CompCurve(wire) self.shape = wire
def discretize(cls, wire, deflection, method='quasi-deflection'): """ Convert a wire to points. Parameters ---------- deflection: Float or Int Maximum deflection allowed if method is 'deflection' or 'quasi-'defelction' else this is the number of points n: Int Number of points to use methode: Str A value of either 'deflection' or 'abissca' Returns ------- points: List[Point] A list of points that make up the curve """ c = BRepAdaptor_CompCurve(wire) start = c.FirstParameter() end = c.LastParameter() fn = DISCRETIZE_METHODS[method.lower().replace('uniform', '')] a = fn(c, deflection, start, end) if method.endswith('abscissa'): param = lambda i: c.Value(a.Parameter(i)) else: param = lambda i: a.Value(i) return [coerce_point(param(i)) for i in range(1, a.NbPoints() + 1)]
def discretize(cls, wire, deflection=0.01, quasi=True): """ Convert a wire to points. Parameters ---------- deflection: Float Maximum deflection allowed n: Int Number of points to use quasi: Bool If True, use the Quasi variant which is faster but less accurate. Returns ------- points: List[Point] A list of points that make up the curve """ c = BRepAdaptor_CompCurve(wire) start = c.FirstParameter() end = c.LastParameter() if quasi: a = GCPnts_QuasiUniformDeflection(c, deflection, start, end) else: a = GCPnts_UniformDeflection(c, deflection, start, end) return [coerce_point(a.Value(i)) for i in range(1, a.NbPoints() + 1)]
def boundary_curve_from_2_points(p1, p2): # first create an edge e0 = BRepBuilderAPI_MakeEdge(p1, p2).Edge() w0 = BRepBuilderAPI_MakeWire(e0).Wire() # boundary for filling adap = BRepAdaptor_CompCurve(w0) p0_h = BRepAdaptor_HCompCurve(adap) boundary = GeomFill_SimpleBound(p0_h, 1e-6, 1e-6) return boundary
def create_shape(self): d = self.declaration t = self.get_transform() shape = BRepBuilderAPI_MakePolygon() for p in d.points: shape.Add(p.proxy.Transformed(t)) if d.closed: shape.Close() curve = self.curve = BRepAdaptor_CompCurve(shape.Wire()) self.shape = curve.Wire()
def wire_to_curve(wire, tolerance=TOLERANCE, order=GeomAbs_C2, max_segment=200, max_order=12): ''' a wire can consist of many edges. these edges are merged given a tolerance and a curve @param wire: ''' adap = BRepAdaptor_CompCurve(wire) hadap = BRepAdaptor_HCompCurve(adap) from OCCT.Approx import Approx_Curve3d approx = Approx_Curve3d(hadap.GetHandle(), tolerance, order, max_segment, max_order) with assert_isdone(approx, 'not able to compute approximation from wire'): return approx.Curve().GetObject()
def by_wire(cls, wire, curvilinear_knots=False): """ Create by a wire. :param afem.topology.entities.Wire wire: The wire. :param bool curvilinear_knots: Option to determine the knot values of the curve by their curvilinear abscissa. :return: The adaptor curve. :rtype: afem.adaptor.entities.WireAdaptorCurve """ adp_crv = BRepAdaptor_CompCurve(wire.object, curvilinear_knots) return cls(adp_crv)
def optimize_moves(wires, start_point, reverse=False, optimizer_timeout=30): """ Use Dijkstra's algorithm to find the shortest path between a set of wires. Ported from Inkcut Parameters ---------- wires: List[TopoDS_Wire] Unordered set of wires start_point: Point Starting point reverse: Bool Revers the point order Returns ------- wires: List[TopoDS_Wires] Wires in the optimal move order """ if len(wires) < 2: return wires now = time.time() time_limit = now + optimizer_timeout original = wires[:] subpaths = [BRepAdaptor_CompCurve(w) for w in wires] result = [] sp = subpaths[0] p = start_point.proxy while subpaths: best = sys.maxsize shortest = None for sp in subpaths: t = sp.LastParameter() if reverse else sp.FirstParameter() start_point = sp.Value(t) d = p.Distance(start_point) if d < best: best = d shortest = sp t = shortest.FirstParameter() if reverse else shortest.LastParameter() p = shortest.Value(t) result.append(shortest) subpaths.remove(shortest) # time.time() is slow so limit the calls if time.time() > time_limit: result.extend(subpaths) # At least part of it is optimized log.warning("Shortest path search aborted (time limit reached)") break return [sp.Wire() for sp in result]
def to_adaptor_3d(curveType): ''' abstract curve like type into an adaptor3d @param curveType: ''' if isinstance(curveType, TopoDS_Wire): return BRepAdaptor_CompCurve(curveType) elif isinstance(curveType, TopoDS_Edge): return BRepAdaptor_Curve(curveType) elif issubclass(curveType.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType.GetHandle()) elif hasattr(curveType, 'GetObject'): _crv = curveType.GetObject() if issubclass(_crv.__class__, Geom_Curve): return GeomAdaptor_Curve(curveType) else: raise TypeError('allowed types are Wire, Edge or a subclass of Geom_Curve\nGot a %s' % (curveType.__class__))
def create_shape(self): d = self.declaration t = self.get_transform() w, h = d.width, d.height if d.rx or d.ry: rx, ry = d.rx, d.ry if not ry: ry = rx elif not rx: rx = ry # Clamp to the valid range rx = min(w / 2, rx) ry = min(h / 2, ry) # Bottom p1 = gp_Pnt(0 + rx, 0, 0) p2 = gp_Pnt(0 + w - rx, 0, 0) # Right p3 = gp_Pnt(w, ry, 0) p4 = gp_Pnt(w, h - ry, 0) # Top p5 = gp_Pnt(w - rx, h, 0) p6 = gp_Pnt(rx, h, 0) # Left p7 = gp_Pnt(0, h - ry, 0) p8 = gp_Pnt(0, ry, 0) shape = BRepBuilderAPI_MakeWire() e = d.tolerance # Bottom if not p1.IsEqual(p2, e): shape.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge()) # Arc bottom right c = make_ellipse((w - rx, ry, 0), rx, ry) shape.Add( BRepBuilderAPI_MakeEdge( GC_MakeArcOfEllipse(c, p2, p3, False).Value()).Edge()) # Right if not p3.IsEqual(p4, e): shape.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge()) # Arc top right c.SetLocation(gp_Pnt(w - rx, h - ry, 0)) shape.Add( BRepBuilderAPI_MakeEdge( GC_MakeArcOfEllipse(c, p4, p5, False).Value()).Edge()) # Top if not p5.IsEqual(p6, e): shape.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge()) # Arc top left c.SetLocation(gp_Pnt(rx, h - ry, 0)) shape.Add( BRepBuilderAPI_MakeEdge( GC_MakeArcOfEllipse(c, p6, p7, False).Value()).Edge()) # Left if not p7.IsEqual(p8, e): shape.Add(BRepBuilderAPI_MakeEdge(p7, p8).Edge()) # Arc bottom left c.SetLocation(gp_Pnt(rx, ry, 0)) shape.Add( BRepBuilderAPI_MakeEdge( GC_MakeArcOfEllipse(c, p8, p1, False).Value()).Edge()) shape = shape.Wire() shape.Closed(True) else: shape = BRepBuilderAPI_MakePolygon(gp_Pnt(0, 0, 0), gp_Pnt(w, 0, 0), gp_Pnt(w, h, 0), gp_Pnt(0, h, 0), True).Wire() wire = TopoDS.Wire_(BRepBuilderAPI_Transform(shape, t, False).Shape()) self.curve = BRepAdaptor_CompCurve(wire) self.shape = wire
from OCCT.gp import gp_Pnt from OCCT.Approx import Approx_Curve3d from OCCT.GeomAbs import GeomAbs_C2 from OCCT.GeomAPI import GeomAPI_ProjectPointOnCurve # Read wire wire_filename = os.path.join('..', 'assets', 'models', 'wire.brep') shp = TopoDS_Shape() aBuilder = BRep_Builder() breptools.Read(shp, wire_filename, aBuilder) wire = topods.Wire(shp) if wire.IsNull(): raise AssertionError("Wire is Null") # discretize the wire and interpolate using a C2 wireAdaptor = BRepAdaptor_CompCurve(wire) curve = BRepAdaptor_HCompCurve(wireAdaptor) tol = 1e-7 max_segments = 200 max_degrees = 12 approx = Approx_Curve3d(curve, tol, GeomAbs_C2, max_segments, max_degrees) if (approx.IsDone() and approx.HasResult()): an_approximated_curve = approx.Curve() # there are two ways to project a point on this curve, # they both give the same restult # 1st solution: using GeomAPI_ProjectPointOnCurve point_to_project = gp_Pnt(1., 2., 3.) projection = GeomAPI_ProjectPointOnCurve(point_to_project, an_approximated_curve)
def end_point(self): """ Get the end / last point of a TopoDS_Wire or TopoDS_Edge """ curve = BRepAdaptor_CompCurve(self.shape) return self.get_value_at(curve, curve.LastParameter())
def start_point(self): """ Get the first / start point of a TopoDS_Wire or TopoDS_Edge """ curve = BRepAdaptor_CompCurve(self.shape) return self.get_value_at(curve, curve.FirstParameter())