From 6088214107fc6575abb997d3041fd706bcbf9c5c Mon Sep 17 00:00:00 2001 From: pgp Date: Wed, 29 Oct 2025 15:17:38 +0100 Subject: [PATCH] oups --- FCHoneycombMaker.FCMacro | 313 ------------------------------ FCHoneycombMaker.FCMacro.manifest | 4 - FCHoneycombMakerIcon.png | Bin 4508 -> 0 bytes start_WF.FCMacro | 61 ------ 4 files changed, 378 deletions(-) delete mode 100644 FCHoneycombMaker.FCMacro delete mode 100644 FCHoneycombMaker.FCMacro.manifest delete mode 100644 FCHoneycombMakerIcon.png delete mode 100644 start_WF.FCMacro diff --git a/FCHoneycombMaker.FCMacro b/FCHoneycombMaker.FCMacro deleted file mode 100644 index 51b6bfd..0000000 --- a/FCHoneycombMaker.FCMacro +++ /dev/null @@ -1,313 +0,0 @@ -# -*- coding: utf-8 -*- -""" -*************************************************************************** -* Copyright (c) 2018-2019 * -* * -* This file is a supplement to the FreeCAD CAx development system. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU Lesser General Public License (LGPL) * -* as published by the Free Software Foundation; either version 2 of * -* the License, or (at your option) any later version. * -* * -* This software is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU Library General Public License at http://www.gnu.org/licenses * -* for more details. * -* * -* For more information about the GNU Library General Public License * -* write to the Free Software Foundation, Inc., 59 Temple Place, * -* Suite 330, Boston, MA 02111-1307 USA * -* * -*************************************************************************** -""" - - - -""" -FCHoneycombMaker - -This is a macro to aid in creation of a honeycomb grid. Parameters, -including hexagon radius, separation between hexagons, etc., can be modified via an included spreadsheet. -""" - -__title__ = "FCHoneycombMaker" -__author__ = "TheMarkster" -__url__ = "https://github.com/mwganson/FCHoneycombMaker" -__Wiki__ = "https://github.com/mwganson/FCHoneycombMaker/blob/master/README.md" -__date__ = "2020.10.30" #year.month.date -__version__ = __date__ - - - - -import FreeCAD -import math -import Part,Draft,DraftTools -from PySide import QtCore, QtGui -import ProfileLib.RegularPolygon -import Sketcher - -RADIUS = 2 -SEPARATION = .25 -PLATE_WIDTH = 20 -PLATE_LENGTH = 55 -PLATE_HEIGHT = 5 - -FreeCAD.Console.PrintMessage ('\nFCHoneycombMaker v'+__version__+'\n') - - -def makeHexagonSketch(sketchName): - #would use the polygon tool, but is buggy and sometimes creates squares instead of hexagons, so the manual way - sketch = App.ActiveDocument.getObject(sketchName) -#we just place the vertices any old where and then constrain them into place later - sketch.addGeometry(Part.LineSegment(App.Vector(-2.000000,1.448548,0),App.Vector(0.500515,2.469759,0)),False) - sketch.addGeometry(Part.LineSegment(App.Vector(0.500515,2.469759,0),App.Vector(2.000000,1.696951,0)),False) - sketch.addConstraint(Sketcher.Constraint('Coincident',0,2,1,1)) - sketch.addGeometry(Part.LineSegment(App.Vector(2.000000,1.696951,0),App.Vector(2.736140,-0.676675,0)),False) - sketch.addConstraint(Sketcher.Constraint('Coincident',1,2,2,1)) - sketch.addGeometry(Part.LineSegment(App.Vector(2.736140,-0.676675,0),App.Vector(1.000000,-2.415493,0)),False) - sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) - sketch.addGeometry(Part.LineSegment(App.Vector(1.000000,-2.415493,0),App.Vector(-3.000000,-1.000000,0)),False) - sketch.addConstraint(Sketcher.Constraint('Coincident',3,2,4,1)) - sketch.addGeometry(Part.LineSegment(App.Vector(-3.000000,-1.000000,0),App.Vector(-2.000000,1.365748,0)),False) - sketch.addConstraint(Sketcher.Constraint('Coincident',4,2,5,1)) - sketch.addConstraint(Sketcher.Constraint('Coincident',5,2,0,1)) - sketch.addGeometry(Part.Circle(App.Vector(0.000000,0.000000,0),App.Vector(0,0,1),3.535498),False) #construction circle - sketch.addConstraint(Sketcher.Constraint('Coincident',6,3,-1,1)) - sketch.addConstraint(Sketcher.Constraint('Radius',6,3.535498)) - sketch.setDatum(7,App.Units.Quantity('2.000000 mm')) - sketch.addConstraint(Sketcher.Constraint('PointOnObject',4,2,6)) #constrain all vertices to the circumference - sketch.addConstraint(Sketcher.Constraint('PointOnObject',0,1,6)) - sketch.addConstraint(Sketcher.Constraint('PointOnObject',0,2,6)) - sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,2,6)) - sketch.addConstraint(Sketcher.Constraint('PointOnObject',2,2,6)) - sketch.addConstraint(Sketcher.Constraint('PointOnObject',3,2,6)) - sketch.toggleConstruction(6) - sketch.addConstraint(Sketcher.Constraint('Equal',5,0)) #set all lines equal - sketch.addConstraint(Sketcher.Constraint('Equal',0,1)) - sketch.addConstraint(Sketcher.Constraint('Equal',1,2)) - sketch.addConstraint(Sketcher.Constraint('Equal',2,3)) - sketch.addConstraint(Sketcher.Constraint('Equal',3,4)) - sketch.addConstraint(Sketcher.Constraint('Horizontal',0)) #make one of them horizontal - sketch.setExpression('Constraints[7]', u'EditMe.radius') - - - - - -if not App.ActiveDocument: - App.newDocument() -if hasattr(App.ActiveDocument,"EditMe"): - raise StandardError("FCHoneycombMaker Error: Please run only once per document. Create a new document and try again.\n") - -worksheet = App.ActiveDocument.addObject("Spreadsheet::Sheet", "EditMe") -worksheet.setColumnWidth('A',150) -set = worksheet.set - -worksheet.mergeCells('A11:G25') -msg1 = """Instructions: - -You should only run the macro once unless you want to start again from scratch. - -Edit the values in column B to define your honeycomb. You can also edit the objects (plate, arrays, etc.), but it's -probably better to do all the editing here in the spreadsheet at least until you get it more or less like you want it before -doing some final tweaking directly on the objects. - -Hexagon radius -- the circumradius of the individual hexagons (circle with each vertex on its circumference). - -Hexagon separation -- distance between each hexagon, the thickness of the grid produced after cutting the hexagons from the plate. - -Plate dimensions -- sets the dimensions of the plate out of which the honeycomb can be cut. These values are used to calculate -the countX and countY variables. You can delete the plate object if you wish to apply the hexagon arrays to a different structure. - -Tweak X,Y,Z -- Edit these to move both hexagon arrays independently of the plate object, for example to center the arrays inside -the plate. - -CountX and CountY -- number of hexagons in the 2 arrays. These are calculated based on the plate size, radius of hexagons, and -separation between them, but you will probably want to modify these manually. Just remember if you modify them you are replacing -the formulas in those cells with immediate values, and thus they won't be recalulated for you if other changes are made. - -If you would prefer a round plate, simply delete the plate object and replace it with a cylinder, and then use the Tweak values -and countX and countY variables to arrange the hexagon arrays to your liking. - -""" -set('A13', msg1) - - -aliases={'radius':'B2', 'separation':'B3', 'width':'B4', 'length':'B5', 'height':'B6', 'tweakX':'B8','tweakY':'B9','tweakZ':'B10', -'xInterval':'E2', 'yInterval':'E3', 'firstX':'E4', 'firstY':'E5','countX':'E6', 'countY':'E7','array2XPos':'E8','array2YPos':'E9', - - } - -for k,v in aliases.items(): - worksheet.setAlias(v,k) - - - -set('A1', 'User Variables') -set('D1','Calculated Values') -set('A2', 'Hexagon Radius:') -set(aliases['radius'], str(RADIUS)) -set('A3', 'Hexagon Separation:') -set(aliases['separation'], str(SEPARATION)) -set('A4', 'Grid Width:') -set(aliases['width'], str(PLATE_WIDTH)) -set('A5', 'Grid Length:') -set(aliases['length'], str(PLATE_LENGTH)) -set('A6', 'Grid Height:') -set(aliases['height'], str(PLATE_HEIGHT)) -set('A8', 'Tweak X:') -set(aliases['tweakX'],u'0') -set('A9', 'Tweak Y:') -set(aliases['tweakY'],u'0') -set('A10', 'Tweak Z:') -set(aliases['tweakZ'],u'0') - - - - -set('D2','X Interval:') -set(aliases['xInterval'],'=2*sin(60deg)*(B2*2+(B3-0.267949*B2))') -set('D3', 'Y Interval:') -set(aliases['yInterval'], '=2*B2+(B3-0.267949*B2)' ) -set('D4', 'First X:') -set(aliases['firstX'], '=B2') -set('D5', 'First Y:') -set(aliases['firstY'], '=B2') -set('D6', 'Count X:') -set(aliases['countX'], '=round((B5) / E2) + 2') -set('D7', 'Count Y:') -set(aliases['countY'], '=round((B4) / E3) + 2') -set ('D8', 'Array2 XPos:') -set (aliases['array2XPos'], '=sin(60deg)*(B2*2+B3-0.26794899999999999*B2)') -set ('D9', 'Array2 YPos:') -set (aliases['array2YPos'],'=E3/2') - - - - - -#xInterval = float(worksheet.getContents(aliases['xInterval'])) -xInterval = 2*math.sin(math.pi/180.0*60)*(RADIUS*2+(SEPARATION-0.267949)) -yInterval = 2*RADIUS+(SEPARATION-0.267949) -#yInterval = float(worksheet.getContents(aliases['yInterval'])) -firstX = RADIUS -firstY = RADIUS - -countY = int((PLATE_LENGTH) / yInterval) -countX = int((PLATE_WIDTH) / xInterval) - - - - -App.ActiveDocument.addObject("Part::RegularPolygon","HoneycombHexagon") -App.ActiveDocument.HoneycombHexagon.Polygon=6 -App.ActiveDocument.HoneycombHexagon.setExpression('Circumradius','EditMe.radius') -hexagonObject = App.ActiveDocument.getObject("HoneycombHexagon") -Gui.ActiveDocument.getObject("HoneycombHexagon").Visibility=False - - -extrudedHexagonObject = App.ActiveDocument.addObject('Part::Extrusion', 'ExtrudedHexagon') -extrudedHexagonObject.Base = hexagonObject -extrudedHexagonObject.setExpression('LengthFwd','EditMe.height') -extrudedHexagonObject.Solid=True -#extrudedHexagonObject.Placement=App.Placement(App.Vector(firstX,firstY,0),App.Rotation(0,0,0),App.Vector(0,0,0)) -extrudedHexagonObject.setExpression('Placement.Base.x','EditMe.firstX+EditMe.tweakX') -extrudedHexagonObject.setExpression('Placement.Base.y','EditMe.firstY+EditMe.tweakY') -extrudedHexagonObject.setExpression('Placement.Base.z', 'EditMe.tweakZ') - -xvector = App.Vector(xInterval,0,0) -yvector = App.Vector(0, yInterval,0) -if not hasattr(Draft,"make_ortho_array"): - row1Array = Draft.makeArray(extrudedHexagonObject, xvector,yvector,countX,countY,name="HoneycombArray1") - row2Array = Draft.makeArray(extrudedHexagonObject, xvector,yvector,countX,countY,name="HoneycombArray2") -else: - row1Array = Draft.make_ortho_array(extrudedHexagonObject, v_x=xvector,v_y=yvector,n_x=countX,n_y=countY,use_link=False) - row2Array = Draft.make_ortho_array(extrudedHexagonObject, v_x=xvector,v_y=yvector,n_x=countX,n_y=countY,use_link=False) -App.ActiveDocument.recompute() -row2Array.Placement = App.Placement(App.Vector(math.sin(60*math.pi/180.0)*(RADIUS*2+(SEPARATION-0.267949)),yInterval,0),App.Rotation(0,0,0),App.Vector(0,0,0)) -#row2Array.setExpression('Placement.Base.x','sin(60deg) * (EditMe.radius * 2 + (EditMe.separation-0.267949*EditMe.radius))') -row2Array.setExpression('Placement.Base.x','EditMe.array2XPos') -#row2Array.setExpression('Placement.Base.y','EditMe.yInterval/2.0') -row2Array.setExpression('Placement.Base.y','EditMe.array2YPos') -row1Array.setExpression('IntervalX.x','EditMe.xInterval') -row1Array.setExpression('IntervalY.y','EditMe.yInterval') -row1Array.setExpression('NumberX','EditMe.countX') -row1Array.setExpression('NumberY','EditMe.countY') - -row2Array.setExpression('IntervalX.x','EditMe.xInterval') -row2Array.setExpression('IntervalY.y','EditMe.yInterval') -row2Array.setExpression('NumberX','EditMe.countX') -row2Array.setExpression('NumberY','EditMe.countY') - -App.activeDocument().addObject("Part::MultiFuse","Fused_Arrays") -#App.activeDocument().Fused_Arrays.Shapes = [App.activeDocument().HoneycombArray1,App.activeDocument().HoneycombArray2,] -App.activeDocument().Fused_Arrays.Shapes = [row1Array,row2Array,] -if not hasattr(Draft,"make_ortho_array"): - Gui.activeDocument().HoneycombArray1.Visibility=False - Gui.activeDocument().HoneycombArray2.Visibility=False -else: - row1Array.Visibility=False - row2Array.Visibility=False - - -window = QtGui.QApplication.activeWindow() -items=('Part Design Workbench Body','Part Workbench Object') -item,ok = QtGui.QInputDialog.getItem(window, "Select object type", "Select your object type. It can be a Part Design body or a Part Cut object.", items, 0, False) -if ok: - if item == items[0]: #PD Body - - App.ActiveDocument.addObject("Part::Plane", "HoneycombPlane") - App.ActiveDocument.HoneycombPlane.setExpression('Length', u'EditMe.length') - App.ActiveDocument.HoneycombPlane.setExpression('Width', u'EditMe.width') - App.ActiveDocument.HoneycombPlane.setExpression('Placement.Base.x', u'EditMe.array2XPos + EditMe.radius * 2') - App.ActiveDocument.HoneycombPlane.setExpression('Placement.Base.y', u'EditMe.array2YPos + EditMe.radius * 2') - - App.activeDocument().addObject("Part::Cut","BaseFeatureFace") - App.ActiveDocument.getObject("BaseFeatureFace").ViewObject.Visibility=False - App.activeDocument().BaseFeatureFace.Base = App.activeDocument().HoneycombPlane - App.activeDocument().BaseFeatureFace.Tool = App.activeDocument().Fused_Arrays - Gui.activeDocument().HoneycombPlane.Visibility=False - Gui.activeDocument().Fused_Arrays.Visibility=False - App.ActiveDocument.recompute() - App.activeDocument().addObject('PartDesign::Body','HoneycombBody') - App.activeDocument().HoneycombBody.BaseFeature = App.activeDocument().BaseFeatureFace - Gui.activeView().setActiveObject('pdHoneycombBody', App.activeDocument().HoneycombBody) - App.activeDocument().HoneycombBody.newObject("PartDesign::Pad","HoneycombPad") - App.activeDocument().HoneycombPad.Profile = (App.activeDocument().BaseFeature, ["Face1"]) - App.activeDocument().HoneycombPad.Length = 10.0 - App.ActiveDocument.recompute() - Gui.activeDocument().setEdit('HoneycombPad', 0) - Gui.activeDocument().hide("BaseFeature") - App.ActiveDocument.HoneycombPad.setExpression('Length', u'EditMe.height') - App.ActiveDocument.HoneycombPad.Length2 = 100.000000 - App.ActiveDocument.HoneycombPad.Type = 0 - App.ActiveDocument.HoneycombPad.UpToFace = None - App.ActiveDocument.HoneycombPad.Reversed = 0 - App.ActiveDocument.HoneycombPad.Midplane = 0 - App.ActiveDocument.HoneycombPad.Offset = 0.000000 - App.ActiveDocument.recompute() - Gui.activeDocument().resetEdit() - else: #Part object - #plate = Part.makeBox(PLATE_WIDTH,PLATE_LENGTH,PLATE_HEIGHT) - #plate = Part.makeBox(worksheet.B4, worksheet.B5, worksheet.B6) - App.ActiveDocument.addObject("Part::Box", "Plate") - plateObject = App.ActiveDocument.getObject("Plate") - App.ActiveDocument.Plate.setExpression('Length', u'EditMe.length') - App.ActiveDocument.Plate.setExpression('Width', u'EditMe.width') - App.ActiveDocument.Plate.setExpression('Height', u'EditMe.height') - App.ActiveDocument.Plate.setExpression('Placement.Base.x', u'EditMe.array2XPos + EditMe.radius * 2') - App.ActiveDocument.Plate.setExpression('Placement.Base.y', u'EditMe.array2YPos + EditMe.radius * 2') - - App.activeDocument().addObject("Part::Cut","HoneycombGrid") - App.activeDocument().HoneycombGrid.Base = App.activeDocument().Plate - App.activeDocument().HoneycombGrid.Tool = App.activeDocument().Fused_Arrays - Gui.activeDocument().Plate.Visibility=False - Gui.activeDocument().Fused_Arrays.Visibility=False - - - -App.ActiveDocument.recompute() -Gui.SendMsgToActiveView("ViewFit") \ No newline at end of file diff --git a/FCHoneycombMaker.FCMacro.manifest b/FCHoneycombMaker.FCMacro.manifest deleted file mode 100644 index 1441fd5..0000000 --- a/FCHoneycombMaker.FCMacro.manifest +++ /dev/null @@ -1,4 +0,0 @@ -[ - "/home/pgp/.var/app/org.freecad.FreeCAD/data/FreeCAD/Macro/MultiExport-FreeCAD/FCHoneycombMaker.FCMacro", - "/home/pgp/.var/app/org.freecad.FreeCAD/data/FreeCAD/Macro/MultiExport-FreeCAD/FCHoneycombMakerIcon.png" -] \ No newline at end of file diff --git a/FCHoneycombMakerIcon.png b/FCHoneycombMakerIcon.png deleted file mode 100644 index 8b4f43bd3daa6c0bea26836e4655267338cf2e62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4508 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