Macros recipes: Difference between revisions

From FreeCAD Documentation
No edit summary
Line 15: Line 15:
This macro copies the selected object several times, on an array grid. You can define the number of rows and columns and the distance between them. You need [http://en.wikipedia.org/wiki/PyQt pyqt] installed.
This macro copies the selected object several times, on an array grid. You can define the number of rows and columns and the distance between them. You need [http://en.wikipedia.org/wiki/PyQt pyqt] installed.


import FreeCAD, FreeCADGui, Part
import FreeCAD, FreeCADGui, Part
from PyQt4 import QtGui,QtCore
from PyQt4 import QtGui,QtCore
def proceed():
def proceed():
try:
try:
u = (int(l1.text()),float(l2.text()))
u = (int(l1.text()),float(l2.text()))
v = (int(l3.text()),float(l4.text()))
v = (int(l3.text()),float(l4.text()))
except:
except:
FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n")
FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n")
sel = FreeCADGui.Selection.getSelection()
sel = FreeCADGui.Selection.getSelection()
if sel:
if sel:
sel = sel[0]
sel = sel[0]
name = sel.Name
name = sel.Name
shape = sel.Shape
shape = sel.Shape
for column in range(u[0]):
for column in range(u[0]):
for row in range(v[0]):
for row in range(v[0]):
if (column != 0) or (row != 0):
if (column != 0) or (row != 0):
delta = FreeCAD.Vector(column*u[1],row*v[1],0)
delta = FreeCAD.Vector(column*u[1],row*v[1],0)
newshape = sel.Shape
newshape = sel.Shape
newshape.translate(delta)
newshape.translate(delta)
newobject = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
newobject = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
newobject.Shape = newshape
newobject.Shape = newshape
else:
else:
FreeCAD.Console.PrintError("Error: One object must be selected")
FreeCAD.Console.PrintError("Error: One object must be selected")
hide()
hide()
def hide():
def hide():
dialog.hide()
dialog.hide()
dialog = QtGui.QDialog()
dialog = QtGui.QDialog()
dialog.resize(200,300)
dialog.resize(200,300)
dialog.setWindowTitle("Array")
dialog.setWindowTitle("Array")
la = QtGui.QVBoxLayout(dialog)
la = QtGui.QVBoxLayout(dialog)
t1 = QtGui.QLabel("number of columns")
t1 = QtGui.QLabel("number of columns")
la.addWidget(t1)
la.addWidget(t1)
l1 = QtGui.QLineEdit()
l1 = QtGui.QLineEdit()
la.addWidget(l1)
la.addWidget(l1)
t2 = QtGui.QLabel("distance between columns")
t2 = QtGui.QLabel("distance between columns")
la.addWidget(t2)
la.addWidget(t2)
l2 = QtGui.QLineEdit()
l2 = QtGui.QLineEdit()
la.addWidget(l2)
la.addWidget(l2)
t3 = QtGui.QLabel("number of rows")
t3 = QtGui.QLabel("number of rows")
la.addWidget(t3)
la.addWidget(t3)
l3 = QtGui.QLineEdit()
l3 = QtGui.QLineEdit()
la.addWidget(l3)
la.addWidget(l3)
t4 = QtGui.QLabel("distance between rows")
t4 = QtGui.QLabel("distance between rows")
la.addWidget(t4)
la.addWidget(t4)
l4 = QtGui.QLineEdit()
l4 = QtGui.QLineEdit()
la.addWidget(l4)
la.addWidget(l4)
okbox = QtGui.QDialogButtonBox(dialog)
okbox = QtGui.QDialogButtonBox(dialog)
okbox.setOrientation(QtCore.Qt.Horizontal)
okbox.setOrientation(QtCore.Qt.Horizontal)
okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
la.addWidget(okbox)
la.addWidget(okbox)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), proceed)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), proceed)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), hide)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), hide)
QtCore.QMetaObject.connectSlotsByName(dialog)
QtCore.QMetaObject.connectSlotsByName(dialog)
dialog.show()
dialog.show()


=== Flatten wire ===
=== Flatten wire ===

Revision as of 21:44, 10 September 2010

Rotate the view by 90°

This macro rotates the current view by 90° to the left. Only works if you are in Top view.

import math
from pivy import coin
cam = Gui.ActiveDocument.ActiveView.getCameraNode()
rot = coin.SbRotation()
rot.setValue(coin.SbVec3f(0,0,1),math.pi/2)
nrot = cam.orientation.getValue() * rot
cam.orientation = nrot

Array copy

This macro copies the selected object several times, on an array grid. You can define the number of rows and columns and the distance between them. You need pyqt installed.

import FreeCAD, FreeCADGui, Part
from PyQt4 import QtGui,QtCore

def proceed():
    try:
        u = (int(l1.text()),float(l2.text()))   
        v = (int(l3.text()),float(l4.text()))
    except:
        FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n")
    sel = FreeCADGui.Selection.getSelection()
        if sel:
            sel = sel[0]
            name = sel.Name   
            shape = sel.Shape
            for column in range(u[0]):
                for row in range(v[0]):
                    if (column != 0) or (row != 0):
                        delta = FreeCAD.Vector(column*u[1],row*v[1],0)   
                        newshape = sel.Shape
                        newshape.translate(delta)
                        newobject = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
                        newobject.Shape = newshape
        else:
            FreeCAD.Console.PrintError("Error: One object must be selected")
        hide()

def hide():
    dialog.hide()

dialog = QtGui.QDialog()
dialog.resize(200,300)
dialog.setWindowTitle("Array")
la = QtGui.QVBoxLayout(dialog)
t1 = QtGui.QLabel("number of columns")
la.addWidget(t1)
l1 = QtGui.QLineEdit()
la.addWidget(l1)
t2 = QtGui.QLabel("distance between columns")
la.addWidget(t2)
l2 = QtGui.QLineEdit()
la.addWidget(l2)
t3 = QtGui.QLabel("number of rows")
la.addWidget(t3)
l3 = QtGui.QLineEdit()
la.addWidget(l3)
t4 = QtGui.QLabel("distance between rows")   
la.addWidget(t4)
l4 = QtGui.QLineEdit()
la.addWidget(l4)
okbox = QtGui.QDialogButtonBox(dialog)
okbox.setOrientation(QtCore.Qt.Horizontal)
okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
la.addWidget(okbox)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), proceed)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), hide)
QtCore.QMetaObject.connectSlotsByName(dialog)
dialog.show()

Flatten wire

This macro flattens draft wires that are not plane to their median Z coordinate.

import FreeCAD
obj = FreeCAD.ActiveDocument.ActiveObject
z = 0
for p in obj.Points: z += p.z
z = z/len(obj.Points)
newpoints = []
for p in obj.Points: newppoints.append(FreeCAD.Vector(p.x,p.y,z))
obj.Points = newppoints

Convert Meshes to Parts

This macro converts selected meshes to parts. It has a broad tolerance, so use it only with objects that have no curves otherwise you'll get weird results.

import FreeCAD,FreeCADGui,Mesh,Part,MeshPart

for obj in FreeCADGui.Selection.getSelection():
	if "Mesh" in obj.PropertiesList:
		faces = []		
		mesh = obj.Mesh
		segments = mesh.getPlanes(0.01) # use rather strict tolerance here

		for i in segments:
		  if len(i) > 0:
		     # a segment can have inner holes
		     wires = MeshPart.wireFromSegment(mesh, i)
		     # we assume that the exterior boundary is that one with the biggest bounding box
		     if len(wires) > 0:
		        ext = None
		        max_length = 0
		        for i in wires:		
		           if i.BoundBox.DiagonalLength > max_length:
		              max_length = i.BoundBox.DiagonalLength
		              ext = i
	        	wires.remove(ext)
	        	# all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
	        	for i in wires:
	        	   i.reverse()
	        	# make sure that the exterior wires comes as first in the lsit
	        	wires.insert(0, ext)
	        	faces.append(Part.Face(wires))

		shell=Part.Compound(faces)
		solid = Part.Solid(Part.Shell(faces))
		name = obj.Name
		FreeCAD.ActiveDocument.removeObject(name)
		FreeCAD.ActiveDocument.addObject("Part::Feature",name).Shape = solid