Macro EdgesToArc/pl

EdgesToArc

Opis
Zastępuje wybrane krawędzie łukiem kołowym, jeśli jest to możliwe. Przydatne do przywracania zdyskretyzowanych łuków.

Macro version: 1.0
Last modified: 2014-01-02
FreeCAD version: All
Download: Ikona paska narzędzi
Autor: Jreinhardt
Autor
Jreinhardt
Do pobrania
Ikona paska narzędzi
Odnośniki
Wersja Makrodefinicji
1.0
Data zmian
2014-01-02
Wersja FreeCAD
All
Domyślny skrót
Brak
Zobacz również
Macro SuperWire

Opis

Czasami trafia się na polilinie zawierające łuki złożone z małych odcinków prostych. Zdarza się to często podczas pracy z plikami z innych programów. To makro ułatwia konwersję takich zdyskretyzowanych łuków z powrotem na łuki kołowe. Dzięki temu zmniejsza się rozmiar pliku i poprawia jego wygodę obsługi.

Aby użyć tego makra, najpierw musisz rozłożyć polilinię na pojedyncze krawędzie za pomocą funkcji Draft Downgrade. Następnie zaznacz segmenty, które chcesz zastąpić łukiem kołowym, i uruchom makro. Wymagane są co najmniej dwa segmenty.

Makro sprawdzi, czy zaznaczone segmenty leżą na wspólnym okręgu i przerwie działanie, jeśli tak nie jest. W przeciwnym razie utworzy łuk i usunie zaznaczone segmenty.

Z powodu drobnych niedokładności w obliczeniach funkcja Draft Upgrade czasami nie radzi sobie z ponownym połączeniem krawędzi i łuków w polilinię. W takim przypadku Macro_SuperWire/pl oferuje bardziej niezawodne rozwiązanie.

Skrypt

ToolBar Icon

Macro_EdgesToArc.FCMacro

import Draft
import FreeCADGui, FreeCAD
from FreeCAD import Base, Console
from math import atan2, pi, fabs

#This macro replaces a number of edges approximating a circular arc by a proper circular arc.
#It might be necessary to use the superwire macro to recombine the edges back to a wire, because of small errors in the calculations.

sel = FreeCADGui.Selection.getSelection()
if len(sel) < 2:
    Console.PrintError("Too few edges are selected\n")
edges = [s.Shape for s in sel]

start_vertices = []
end_vertices = []
for edge in edges:
    start_vertices.append(edge.Vertexes[0].Point)
    end_vertices.append(edge.Vertexes[1].Point)
vertices = start_vertices + end_vertices

start,end,middle = None,None,None

#find start and end points
for edge in edges:
    is_start = True
    is_end = True
    for point in end_vertices:
        if edge.Vertexes[0].Point.distanceToPoint(point) < 1e-8:
            is_start = False

    for point in start_vertices:
        if edge.Vertexes[1].Point.distanceToPoint(point) < 1e-8:
            is_end = False
    if is_start:
        start = edge.Vertexes[0].Point
    if is_end:
        end = edge.Vertexes[1].Point

#find middle point, at least not too far away from the middle

for v in vertices:
    ratio = v.distanceToPoint(start)/v.distanceToPoint(end)
    if ratio > 0.5 and ratio < 2.:
        middle = v
        break

if middle is None:
    Console.PrintError("Could not find suitable middle point\n")

arc = Part.ArcOfCircle(start,middle,end)

#Check circularity
circular = True
for v in vertices:
    if fabs(v.distanceToPoint(arc.Center) - arc.Radius) > 1e-6:
        Console.PrintError("Edges do not approximate a circular arc\n")
        circular = False
        break

if circular:
        Part.show(arc.toShape())
        for shape in sel:
            FreeCAD.ActiveDocument.removeObject(shape.Name)