User:Piffpoof

From FreeCAD Documentation
Revision as of 10:41, 18 January 2015 by Piffpoof (talk | contribs)

hi there

This is the user page for PiffPoof. Our use of FreeCAD and our membership on this forum started as a project to document a 40 year old sailing boat. Lots of information about the boat and the work done on it over the last 10 years is available at https://maringret.wordpress.com/. This page describes our FreeCAD specific activities.

The builders no longer had drawings and the son of the first owner of the boat building company doubted there ever were full drawings. Apparently they built things "by eye" before CAD. Consequently the hull dimensions had to be measured and then a model constructed within the software, Modern software packages like FreeCAD offer many beneficial features like symmetry constraints but when the final measurement is a model that is "easy on the eye" much "massaging" of models and data is required.

Current state of the project: 400+ objects and counting...

We started by modeling the interior (it was easiest to measure) and quickly reached 150 objects. We were barely started and so it was at that point that we started to realise that we would be swamped by the sheer complexity of the undertaking unless we could sub-divide the project and automate as much as possible.This also marked the point where we started to construct tools we needed to manage our complexity explosion.

We developed a few utilities and systems for our own purposes. Due to the open nature of the FreeCAD community we tried to keep them open enough to be used for other uses and by other persons. At present we have the following items in various stages of development:

Programming Software

Macro_Dump_Objects

  • v 0.2
  • operational
  • documented
  • uploaded

Navigation Utility Suite

  • a toolbar consisting of 3 macros that enhance managing the FreeCAD user interface, in addition 2 existing FreeCAD macros are included
  • v 1.0 operational
  • documented
  • uploaded

Build Utility

  • v 1.0 operational
  • not documented
  • not uploaded

Python Console Assistant

  • under development
  • working as prototype

Visibility Management Assistant

  • anticipated

Marine Software

Half Hull Designer

  • helps in the design of half-hull models of ship hulls
  • under development
  • working as prototype

Wiring & Hoses

  • provides the facility to run wires and hoses through three dimensional models (e.g. buildings, ships, planes, machinery)
  • under development
  • working as prototype



#
#						Dump Object
#                       v 0.2 - added report to CSV file
#                       v 0.1 - added report to window
#                       v 0.0 - report to Report view
#
#***********************************************************************************
# routine to dump object space for Geometric model in the currently active file

from PySide import QtGui, QtCore
from datetime import datetime # datestamp on output window
from os.path import expanduser # output directory for CSV

# Class definitions

class configureMacro(QtGui.QDialog):
	""""""
	def __init__(self):
		super(configureMacro, self).__init__()
		self.initUI()
	def initUI(self):
		self.result			= None
		# set up display only field for selected path type
		self.cbss			= QtGui.QCheckBox("Show Sketcher Segments?", self)
		self.cbss.move(20,20)
		self.cbp			= QtGui.QCheckBox("Show Positions?", self)
		self.cbp.move(220,20)
		self.pathTypeLbl	= QtGui.QLabel("Select Report Destination:", self)
		self.pathTypeLbl.move(20, 70)
		# cancel button
		cancelButton = QtGui.QPushButton('Cancel', self)
		cancelButton.clicked.connect(self.onCancel)
		cancelButton.move(10, 100)
		# button #1
		button1 = QtGui.QPushButton(choice1, self)
		button1.clicked.connect(self.onBtn1)
		button1.move(120, 100)
		# button #2
		button2 = QtGui.QPushButton(choice2, self)
		button2.clicked.connect(self.onBtn2)
		button2.move(235, 100)
		# button #3
		button3 = QtGui.QPushButton(choice3, self)
		button3.clicked.connect(self.onBtn3)
		button3.move(327, 100)
		# define window		xLoc,yLoc,xDim,yDim
		self.setGeometry(	250, 250, 435, 150)
		self.setWindowTitle("Select a Report Destination")
		self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
		self.show()
	def onCancel(self):
		self.result = "cancelled"
		self.close()
	def onBtn1(self):
		self.result = choice1
		self.close()
	def onBtn2(self):
		self.result = choice2
		self.close()
	def onBtn3(self):
		self.result = choice3
		self.close()

class DisplayText(QtGui.QWidget):
#class DisplayText(QtGui.QMainWindow):
	""""""
	def __init__(self, textToDisplay):
		self.text = textToDisplay
		super(DisplayText, self).__init__()
		self.initUI(textToDisplay)
	def initUI(self, textToDisplay):
		"""Constructor"""
		self.textToDisplay = textToDisplay
		# some window dimensions
		self.windowHome = screenWidth * 0.05
		self.windowWidth = screenWidth * 0.9
		self.windowHeight = 400
		self.fieldMargin = 40
		# some column titles
		columnLabels = QtGui.QLabel(formatPrintLine("Type / WB","Shape","User Supplied Label","Name"))
		columnLabels.setFont('Courier')
		# set up text editing widget
		text_editor = QtGui.QTextEdit(self)
		#self.setCentralWidget(self.text_editor)
		text_editor.setFont('Courier')
		text_editor.setLineWrapMode(QtGui.QTextEdit.NoWrap)
		text_editor.move(self.fieldMargin,self.fieldMargin)
		text_editor.move(0,self.fieldMargin)
		text_editor.resize(self.windowWidth-(2*self.fieldMargin),self.windowHeight-(2*self.fieldMargin))
		text_editor.resize(self.windowWidth,self.windowHeight-(2*self.fieldMargin))
		text_editor.append(self.textToDisplay)
		# set up the layout
		vBox = QtGui.QVBoxLayout()
		vBox.addWidget(columnLabels)
		vBox.addWidget(text_editor)
		self.setLayout(vBox)
		# define window		xLoc,yLoc,xDim,yDim
		self.setGeometry(	self.windowHome, self.windowHome, self.windowWidth, self.windowHeight)
		self.setWindowTitle("Object Dump of '" + FreeCADGui.ActiveDocument.Document.Label + "' at " + str(datetime.now()))
		self.show()
	#----------------------------------------------------------------------
	def onOk(self):
		self.close()

# define functions

def countObjects():
	printList = list()
	objectTypeTable = {}
	# build up dictionary of different classes and keep a count
	for obj in FreeCAD.ActiveDocument.Objects:
		if objectTypeTable.has_key(obj.TypeId):
			objectTypeTable[obj.TypeId] = objectTypeTable[obj.TypeId]+1
		else:
			objectTypeTable[obj.TypeId] = 1
		wb = obj.TypeId[0:obj.TypeId.find("::")]
		shape = obj.TypeId[obj.TypeId.find("::")+2:]
		placementString = ""
		if obj.TypeId == "Sketcher::SketchObject":
			printList.append(formatPrintLine("Sketch", "", str(obj.Label)))
			if showSketcherSegmentsFlag:
				for i in obj.Geometry:
					printList.append(formatPrintLine("", " -segment", str(i)))
		elif wb == "Part":
			if showPlacementFlag:
				placementString = str(obj.Placement)
			if shape in ("Cylinder", "Cut", "Box", "Fuse", "Loft", "Feature", "Part2DObjectPython"):
				printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
			elif obj.TypeId == "Part::Feature":
				printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
			elif obj.TypeId == "Part::Part2DObjectPython":
				printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
		elif wb == "PartDesign":
			if showPlacementFlag:
				placementString = str(obj.Placement)
			if shape in ("Pad", "Fillet"):
				printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))
			elif obj.TypeId == "Part::Feature":
				printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
			elif obj.TypeId == "Part::Part2DObjectPython":
				printList.append(formatPrintLine(str(obj.TypeId), "", str(obj.Label), str(obj.Name)))
		elif obj.TypeId == "App::DocumentObjectGroup":
			printList.append(formatPrintLine("Group", "", str(obj.Label)))
		elif obj.TypeId == "Image::ImagePlane":
			printList.append(formatPrintLine(wb, shape, str(obj.Label), str(obj.Name)))		
		else:
			printList.append(formatPrintLine(str(obj.TypeId), str(obj.Label), str(obj.Name)))
		if showPlacementFlag and len(placementString)!=0:
			printList.append(formatPrintLineMax("", " -placement", placementString))

	printList.append("")
	printList.append(summarySeparator)
	from collections import OrderedDict
	sortedByTags = OrderedDict(sorted(objectTypeTable.items(), key=lambda x: x[1], reverse=True))
	for k, v in sortedByTags.items():
		printList.append(formatPrintLineSum(k,v))
	printList.append("")
	objectClassCount = 0; objectTotalCount = 0
	for i in objectTypeTable:
		objectTotalCount = objectTotalCount + objectTypeTable[i]
	objectCLassCount = len(objectTypeTable)
	printList.append(formatPrintLineSum("Object Class Total is ", str(objectCLassCount)))
	printList.append(formatPrintLineSum("Object Total is ", str(objectTotalCount)))
	printList.append(summarySeparator)
	return printList

def formatPrintLineSum(a,b):
	return printLineFormatter(2, a, str(b), "", "")

def formatPrintLineMax(a,b,c):
	return printLineFormatter(1, a, b, "", "")

def formatPrintLine(a,b,c, *args):
	d = ""
	if len(args)==1:
		d = args[0]
	return printLineFormatter(0, a, b, c, d)

def printLineFormatter(flag,a,b,c,d):
	# flag = 0	standard print, spread values over 4 columns
	# flag = 1	printing verbose things like Sketch details or Placements, combine columns 3 & 4
	# flag = 2	printing the summary lines, combine columns 1 & 2
	suffix = ""
	if csvFlag:
		pfs2 = printFormatString2csv
		pfs3 = printFormatString3csv
		pfs4 = printFormatString4csv
	else:
		pfs2 = printFormatString2
		pfs3 = printFormatString3
		pfs4 = printFormatString4
	if flag==0:
		aa = a[:f1]
		bb = b[:f2]
		cc = c[:f3]
		dd = d[:f4]
		return pfs4.format(aa,bb,cc,dd)
	elif flag==1:
		aa = a[:f1]
		bb = b[:f2]
		cc = c[:f3+f4]
		dd = d[:f4]
		return pfs3.format(aa,bb,cc)
	else:
		aa = a[:f1+f2]
		bb = b[:f3+f4]
		return pfs2.format(aa,bb)

# constants
# set some field widths
screenWidth = QtGui.QDesktopWidget().screenGeometry().width()
global f1, f2, f3, f4
# f1 = 15; f2 = 25; f3 = 45; f4 = 25 # 110 columns in 1000 pixels
f1 = 15*screenWidth/1000; f2 = 25*screenWidth/1000; f3 = 45*screenWidth/1000; f4 = 25*screenWidth/1000
# and some print format strings
global printFormatString2, printFormatString3, printFormatString4
global printFormatString2csv, printFormatString3csv, printFormatString4csv
printFormatString2 = "{0:<"+str(f1+f2)+"} {1:<"+str(f3)+"}"
printFormatString2csv = "{0}, {1}"
printFormatString3 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3+f4)+"}"
printFormatString3csv = "{0}, {1}, {2}"
printFormatString4 = "{0:<"+str(f1)+"} {1:<"+str(f2)+"} {2:<"+str(f3)+"} {3:<"+str(f4)+"}"
printFormatString4csv = "{0}, {1}, {2}, {3}"
# some button labels that are checked in the code
global choice1, choice2, choice3, csvFlag
choice1 = "Report View"; choice2 = "CSV File"; choice3 = "Window"
csvFlag = False
summarySeparator = "======================================================="
# code ***********************************************************************************
if FreeCAD.ActiveDocument != None:
	# ask if to window or to Report View...
	form = configureMacro()
	form.exec_()
	showSketcherSegmentsFlag = False
	if form.cbss.isChecked():
		showSketcherSegmentsFlag = True
	showPlacementFlag = False
	if form.cbp.isChecked():
		showPlacementFlag = True
	if form.result == choice2:
		csvFlag = True
		summarySeparator = "-------------------------------------------------------"
	printList = countObjects()
	if form.result == choice1: # report to Report View
		print printFormatString4.format(	"", "", "(User Supplied)", "")
		print printFormatString4.format(	"Type", "Shape", "Label", "Name")
		print ""
		for line in printList:
			print line + "\n"
	if form.result == choice2: # report to CSV file
		homeDir = expanduser("~")
		file = open(homeDir+"/test.csv","w")
		for line in printList:
			file.write(line + "\n")
		file.close()
	if form.result == choice3: # report to window
		#----------------------------------------------------------------------
		longPrintLine = ""
		for line in printList:
			longPrintLine = longPrintLine + line + "\n"
		form = DisplayText(longPrintLine)
#
#OS: Mac OS X
#Word size: 64-bit
#Version: 0.14.3703 (Git)
#Branch: releases/FreeCAD-0-14
#Hash: c6edd47334a3e6f209e493773093db2b9b4f0e40
#Python version: 2.7.5
#Qt version: 4.8.6
#Coin version: 3.1.3
#SoQt version: 1.5.0
#OCC version: 6.7.0
#