Piffpoof Macro Half-Hull Model

QtGui.QMessageBox.No, QtGui.QMessageBox.No)		if reply == QtGui.QMessageBox.Yes:			FreeCAD.closeDocument(outputWorkspaceB)		else:			userAction = userCancelled

if userAction!=userCancelled: # bring in values from user dialogue coachhouseFlag			= aDictionary["coachhouseDeckBulkheadsFlag"] forwardBulkheadsToSkip	= aDictionary["forwardBulkheadsToSkip"] aftBulkheadsToSkip		= aDictionary["aftBulkheadsToSkip"] deckWidth				= aDictionary["deckWidth"] deckThrow				= aDictionary["deckThrow"] coachhouseRise			= aDictionary["coachhouseRise"] coachhouseIncline		= aDictionary["coachhouseIncline"] # set up output workspaces doc = FreeCAD.newDocument(outputWorkspaceB) FreeCAD.setActiveDocument(outputWorkspaceB) FreeCAD.ActiveDocument = FreeCAD.getDocument(outputWorkspaceB) FreeCADGui.ActiveDocument = FreeCADGui.getDocument(outputWorkspaceB) for i in range(forwardBulkheadsToSkip,len(crossSections)-aftBulkheadsToSkip): # add new bulkhead cs = crossSections[i] newSketch = FreeCAD.activeDocument.addObject('Sketcher::SketchObject',cs.label) #place bulkhead along keel newSketch.Placement = FreeCAD.Placement(				FreeCAD.Vector(cs.xPos,cs.yPos,cs.zPos),				FreeCAD.Rotation(cs.rotQ1,cs.rotQ2,cs.rotQ3,cs.rotQ4)) # insert geometry segments from both half-hulls plus bulkhead into new Sketch for seg in cs.geometryC: newSketch.addGeometry(					Part.Line(FreeCAD.Vector(seg.StartPoint.x,						seg.StartPoint.y,	0), FreeCAD.Vector(seg.EndPoint.x,						seg.EndPoint.y,0))) FreeCAD.ActiveDocument.recompute xMin = cs.xMax * -1 if coachhouseFlag: # user wants a coachhouse bulkhead newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(xMin, cs.yMax, 0), FreeCAD.Vector(xMin+deckWidth, cs.yMax+deckThrow, 0))) FreeCAD.ActiveDocument.recompute newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(xMin+deckWidth, cs.yMax+deckThrow, 0), FreeCAD.Vector(xMin+deckWidth+coachhouseIncline, cs.yMax+deckThrow+coachhouseRise, 0))) FreeCAD.ActiveDocument.recompute #				newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(xMin+deckWidth+coachhouseIncline, cs.yMax+deckThrow+coachhouseRise, 0), FreeCAD.Vector(cs.xMax-deckWidth-coachhouseIncline, cs.yMax+deckThrow+coachhouseRise, 0))) FreeCAD.ActiveDocument.recompute # focus at about -800 #newSketch.addGeometry(				#	Part.ArcOfCircle(Part.Circle(App.Vector(0.0,-190,0),App.Vector(0,0,1),240.0),1.078868,2.064096)) newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(cs.xMax-deckWidth-coachhouseIncline, cs.yMax+deckThrow+coachhouseRise, 0), FreeCAD.Vector(cs.xMax-deckWidth, cs.yMax+deckThrow, 0))) FreeCAD.ActiveDocument.recompute newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(cs.xMax-deckWidth, cs.yMax+deckThrow, 0), FreeCAD.Vector(cs.xMax, cs.yMax, 0))) else: # generate bulkheads for flush deck newSketch.addGeometry(					Part.Line(	FreeCAD.Vector(xMin, cs.yMax, 0), FreeCAD.Vector(cs.xMax, cs.yMax, 0))) FreeCAD.ActiveDocument.recompute newPad = App.activeDocument.addObject("PartDesign::Pad","Bulkhead") newPad.Sketch = newSketch newPad.Length = 1.0 newPad.Sketch.ViewObject.hide FreeCAD.ActiveDocument.recompute FreeCADGui.SendMsgToActiveView("ViewFit") FreeCADGui.activeDocument.activeView.viewAxometric

def createPlaque(aSideFlag, aKeelFlag): # create plaque to mount half-hull on	# get some dimensions for the plaque based on the size of the hull or half-hull # note: the X & Y in this routine are to do with the XY of the plaque, not the Sketches woodColour = (0.53, 0.42, 0.23, 0.0) # find the overall max & min for X & Y	minusY = crossSections[1].yMin; plusY = crossSections[1].yMin # get the plaque's Y min & max for the cross-sections (not the stemline or transom) for i in range(1,len(crossSections)-1): minusY = min(minusY, crossSections[i].yMin) plusY = max(plusY, crossSections[i].yMax) # now allow for the extent of the stemline minusY = min(minusY, crossSections[0].yMin) plusY = max(plusY, crossSections[0].yMax) # get extent of aftmost cross-section and add what the transom sticks out minusX = crossSections[-2].yPos + crossSections[-1].yMin - crossSections[-1].yMax # get the placement of the stemline and add what the stemline extends forward plusX = crossSections[0].yPos + crossSections[0].xMax # some scaling factors to provide margin space around the half-hull minusX = minusX * 1.1 plusX = plusX * 1.1 minusY = minusY * 1.5 plusY = plusY * 1.25

ps = FreeCAD.activeDocument.addObject('Sketcher::SketchObject','PlainPlaqueSketch') ps.Placement = FreeCAD.Placement(FreeCAD.Vector(0.0,0.0,0.0),									FreeCAD.Rotation(0.5,0.5,0.5,0.5)) if aSideFlag==starboardSideFlag: ps.Placement.Base.x = -10 ps.addGeometry(Part.Line(FreeCAD.Vector(minusX,plusY,0),FreeCAD.Vector(plusX,plusY,0))) ps.addGeometry(Part.Line(FreeCAD.Vector(plusX,plusY,0),FreeCAD.Vector(plusX,minusY,0))) ps.addGeometry(Part.Line(FreeCAD.Vector(plusX,minusY,0),FreeCAD.Vector(minusX,minusY,0))) ps.addGeometry(Part.Line(FreeCAD.Vector(minusX,minusY,0),FreeCAD.Vector(minusX,plusY,0))) #	ps.addConstraint(Sketcher.Constraint('Coincident',0,2,1,1)) ps.addConstraint(Sketcher.Constraint('Coincident',1,2,2,1)) ps.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) ps.addConstraint(Sketcher.Constraint('Coincident',3,2,0,1)) ps.addConstraint(Sketcher.Constraint('Horizontal',0)) ps.addConstraint(Sketcher.Constraint('Horizontal',2)) ps.addConstraint(Sketcher.Constraint('Vertical',1)) ps.addConstraint(Sketcher.Constraint('Vertical',3)) FreeCAD.ActiveDocument.recompute #	pad = FreeCAD.activeDocument.addObject("PartDesign::Pad","PlainPlaquePad") pad.Sketch = ps	pad.Length = 10.0 pad.Sketch.ViewObject.hide pad.ViewObject.ShapeColor = woodColour FreeCAD.ActiveDocument.recompute #	cyl1 = FreeCAD.ActiveDocument.addObject("Part::Cylinder","Cylinder1") cyl1.Label = "Cylinder1" cyl1.Radius = plusY/5 cyl1.Placement =	FreeCAD.Placement(FreeCAD.Vector(0,plusX,plusY),						FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90)) if aSideFlag==starboardSideFlag: cyl1.Placement.Base.x = -10 cut1 = FreeCAD.activeDocument.addObject("Part::Cut","Cut1") cut1.Base = App.activeDocument.PlainPlaquePad cut1.Tool = App.activeDocument.Cylinder1 cut1.ViewObject.ShapeColor = woodColour FreeCAD.ActiveDocument.recompute #	cyl2 = FreeCAD.ActiveDocument.addObject("Part::Cylinder","Cylinder2") cyl2.Label = "Cylinder2" cyl2.Radius = plusY/5 cyl2.Placement =	FreeCAD.Placement(FreeCAD.Vector(0,plusX,minusY),						FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90)) if aSideFlag==starboardSideFlag: cyl2.Placement.Base.x = -10 cut2 = FreeCAD.activeDocument.addObject("Part::Cut","Cut2") cut2.Base = App.activeDocument.Cut1 cut2.Tool = App.activeDocument.Cylinder2 cut2.ViewObject.ShapeColor = woodColour FreeCAD.ActiveDocument.recompute #	cyl3 = FreeCAD.ActiveDocument.addObject("Part::Cylinder","Cylinder3") cyl3.Label = "Cylinder3" cyl3.Radius = plusY/5 cyl3.Placement =	FreeCAD.Placement(FreeCAD.Vector(0,minusX,minusY),						FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90)) if aSideFlag==starboardSideFlag: cyl3.Placement.Base.x = -10 cut3 = FreeCAD.activeDocument.addObject("Part::Cut","Cut3") cut3.Base = App.activeDocument.Cut2 cut3.Tool = App.activeDocument.Cylinder3 cut3.ViewObject.ShapeColor = woodColour FreeCAD.ActiveDocument.recompute #	cyl4 = FreeCAD.ActiveDocument.addObject("Part::Cylinder","Cylinder4") cyl4.Label = "Cylinder4" cyl4.Radius = plusY/5 cyl4.Placement =	FreeCAD.Placement(FreeCAD.Vector(0,minusX,plusY),						FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90)) if aSideFlag==starboardSideFlag: cyl4.Placement.Base.x = -10 cut4 = FreeCAD.activeDocument.addObject("Part::Cut","Cut4") cut4.Base = App.activeDocument.Cut3 cut4.Tool = App.activeDocument.Cylinder4 cut4.ViewObject.ShapeColor = woodColour FreeCAD.ActiveDocument.recompute #	cham = FreeCAD.ActiveDocument.addObject("Part::Chamfer","Plaque") cham.Base = FreeCAD.ActiveDocument.Cut4 edges = [] if aSideFlag == starboardSideFlag: edges.append((3,3.00,3.00)); edges.append((13,3.00,3.00)); edges.append((14,3.00,3.00)); edges.append((15,3.00,3.00)) edges.append((16,3.00,3.00)); edges.append((17,3.00,3.00)); edges.append((18,3.00,3.00)); edges.append((19,3.00,3.00)) else: edges.append((1,3.00,3.00)); edges.append((5,3.00,3.00)); edges.append((6,3.00,3.00)); edges.append((7,3.00,3.00)) edges.append((8,3.00,3.00)); edges.append((9,3.00,3.00)); edges.append((10,3.00,3.00)); edges.append((11,3.00,3.00)) cham.Edges = edges cham.Base.ViewObject.Visibility = False cham.ViewObject.ShapeColor = woodColour

createPlaqueCover if aSideFlag == starboardSideFlag: FreeCADGui.activeDocument.activeView.viewRight else: FreeCADGui.activeDocument.activeView.viewLeft FreeCADGui.SendMsgToActiveView("ViewFit") FreeCAD.ActiveDocument.recompute

def createPlaqueCover: # get upper bow point UBP # get upper stern point USP # get number of sections NS	# divide the line UBP-USP into NS pieces #---	# for each sketch, get the top point TP	# make segments between each consecutive points #---	# make RuledSurface between corresponding segments FreeCAD.zot = crossSections if len(crossSections)<5: FreeCAD.Console.PrintMessage("Insufficient cross-sections for plaque cover") else: # the number of cross-section and therefore chines determines how many # segments will be in the cover for the half-hull model segmentCount = len(crossSections)-2 # determine endpoints for the line segments along the plaque bowPoint = Base.Vector(0,			max(crossSections[0].geometryS[-1].StartPoint.x, crossSections[0].geometryS[-1].EndPoint.x),			max(crossSections[0].geometryS[-1].StartPoint.y, crossSections[0].geometryS[-1].EndPoint.y)) sternPoint = Base.Vector(0,			crossSections[-2].yPos,			max(crossSections[-2].geometryS[-1].StartPoint.y, crossSections[-2].geometryS[-1].EndPoint.y)) plaquePoints = [bowPoint, sternPoint] lineAlongPlaqueToSplit = Part.Line(bowPoint,sternPoint) lapSection = lineAlongPlaqueToSplit.length/segmentCount

# build a list of the points that start/end the segments pointList = [] pointList.append(lineAlongPlaqueToSplit.StartPoint) print lineAlongPlaqueToSplit.StartPoint for i in range(1, segmentCount): pointList.append(lineAlongPlaqueToSplit.value((i)*lapSection)) print lineAlongPlaqueToSplit.value((i)*lapSection) pointList.append(lineAlongPlaqueToSplit.EndPoint) print lineAlongPlaqueToSplit.EndPoint print # iterate the list of points from the first segment to the last # do stemline first as it is in the YZ plane (cross-sections are in the XZ plane) a=FreeCAD.ActiveDocument.addObject('Part::Line', 'cs1k') a.X1=0; a.Y1=pointList[0].y; a.Z1=pointList[0].z		a.X2=0; a.Y2=pointList[1].y; a.Z2=pointList[1].z		b=FreeCAD.ActiveDocument.addObject('Part::Line', 'cs1h') # B1 wrong b.X1=0; b.Y1=crossSections[0].endPoint.x; b.Z1=crossSections[0].endPoint.z		b.X2=crossSections[1].endPoint.x; b.Y2=crossSections[1].endPoint.y; b.Z2=crossSections[1].endPoint.z		FreeCAD.ActiveDocument.addObject('Part::RuledSurface', 'coverSeg1') FreeCAD.ActiveDocument.ActiveObject.Curve1=(a,['']) FreeCAD.ActiveDocument.ActiveObject.Curve2=(b,['']) FreeCAD.ActiveDocument.recompute # now do cross=sections for i in range(1, segmentCount): a=FreeCAD.ActiveDocument.addObject('Part::Line', 'cs'+str(i+1)+'k') a.X1=0; a.Y1=pointList[i].y; a.Z1=pointList[i].z			a.X2=0; a.Y2=pointList[i+1].y; a.Z2=pointList[i+1].z			b=FreeCAD.ActiveDocument.addObject('Part::Line', 'cs'+str(i+1)+'h') b.X1=crossSections[i].endPoint.x;  b.Y1=crossSections[i].endPoint.y;   b.Z1=crossSections[i-1].endPoint.z			b.X2=crossSections[i+1].endPoint.x; b.Y2=crossSections[i+1].endPoint.y; b.Z2=crossSections[i].endPoint.z			FreeCAD.ActiveDocument.addObject('Part::RuledSurface', 'coverSeg'+str(i+1)) FreeCAD.ActiveDocument.ActiveObject.Curve1=(a,['']) FreeCAD.ActiveDocument.ActiveObject.Curve2=(b,['']) FreeCAD.ActiveDocument.recompute FreeCAD.ActiveDocument.recompute

def displayChinePanels(crossSectionLabelA, crossSectionLabelB, aSideFlag): # accept 2 sketch labels and generate a ruled surface between them #print sketchLabelA placeholder = "_" csA = FreeCAD.ActiveDocument.getObjectsByLabel(crossSectionLabelA)[0] csB = FreeCAD.ActiveDocument.getObjectsByLabel(crossSectionLabelB)[0] labelA = csA.Label labelB = csB.Label lblA = labelA.split('_', 1)[0] lblB = labelB.split('_', 1)[0] if aSideFlag == portSideFlag: sideText = " Port" elif aSideFlag == starboardSideFlag: sideText = " Starboard" else: sideText = "" #print str(sketchLabelA) + " " + str(sketchLabelB) FreeCAD.ActiveDocument.addObject('Part::RuledSurface', placeholder+lblA+placeholder+lblB+sideText) csObjectA = FreeCAD.ActiveDocument.getObjectsByLabel(crossSectionLabelA)[0] csObjectB = FreeCAD.ActiveDocument.getObjectsByLabel(crossSectionLabelB)[0] #print "> " + str(sketchObjectA) + " " + str(sketchObjectB) FreeCAD.ActiveDocument.ActiveObject.Curve1=(csObjectA,['']) FreeCAD.ActiveDocument.ActiveObject.Curve2=(csObjectB,[''])

def displayCompleteHull: userAction = None

docKey = findOpenDocumentName(outputWorkspaceC) if docKey!=None: reply = QtGui.QMessageBox.question(None, "",			"The previous 'Complete Hull' output file is still open, close it",			QtGui.QMessageBox.Yes