From 712d9ce3351914a4d1418ed2a3a10f0c40bb57b4 Mon Sep 17 00:00:00 2001 From: baleti3266 Date: Sun, 15 Dec 2024 01:31:55 +0000 Subject: [PATCH] Initial commit --- ...nd get all available commands functions.py | 17 ++ $$/DupLayersSublayersAndObjs.py | 52 +++++ ...NG-DUE-TO-VIEWPORTS-STRETCHING-FRUSTUMS.py | 14 ++ ...lAsSeparatePagesMultiprocess-SUPERSEDED.py | 8 + $$/RemapCplaneCopyGUI.py | 31 +++ $$/RemapCplaneGUI-WIP.py | 9 + $$/RemapCplaneGUI.py | 15 ++ $$/ReopenThisFileWithoutSaving-WIP.py | 5 + $$/SelColorOnlyInBlocks.py | 38 ++++ ...CT-MULTIPLE-LAYERS-USE-SELLAYER-INSTEAD.py | 11 + ...elLayerByObject-GOT-A-BIT-CONFUSED-HERE.py | 15 ++ $$/SelMaterialOnlyInBlocks.py | 40 ++++ $$/SelectAllObjsOnObjLayers.py | 9 + ...tWidths-Chetwoods-Standard-ctb-TOO-SLOW.py | 93 ++++++++ $$/ShowSelectedByMatchingLayer.py | 37 ++++ $$/_PrintAllAsSeparatePages.py | 56 +++++ ...in32-conenct-to-a-running-Rhino-process.py | 6 + 1Layout1PDF.py | 21 ++ AbsoluteTolerance.py | 11 + AcadIntegration.py | 15 ++ ...teDetailViewsonLayouts-WORK-IN-PROGRESS.py | 9 + ...G-FOR-LINKED-BLOCKS-AND-CLIPPING-PLANES.py | 78 +++++++ BatchMake2D.py | 70 ++++++ BlockTools 1.4.rhi | Bin 0 -> 17837 bytes BlockUpdate.py | 11 + ...ected-NOT-WORKING-MISSING-UPDATE-OPTION.py | 12 ++ ChangeCameraProjection.py | 24 +++ ChangeLayerInBlockRecursively.py | 34 +++ ChangeMaterial.py | 25 +++ ChangeMaterialForAll.py | 40 ++++ ClipEnableGUI.py | 30 +++ ClipSelGUI.py | 29 +++ ClipSelGUIMultiple.py | 27 +++ ConsolidateLayers.py | 54 +++++ ConvertHatchesToSrfs_cmd.py | 23 ++ ConvertPlanarSrfsToHatch-v8.py | 25 +++ ConvertPlanarSrfsToHatch.py | 25 +++ ConvertProjectV8ToV7.py | 34 +++ ConvertV8ToV7ForFiles.py | 21 ++ DeleteBlock.py | 8 + DeleteNamedCplane.py | 7 + DisableAllClippingPlanes.py | 11 + ...tBox_PrintAllBlockDefinitionsInDocument.py | 204 ++++++++++++++++++ ..._MultipleListBox_PrintSelectedLayerName.py | 204 ++++++++++++++++++ ExportDwgSchemeRGBColors.py | 9 + ExportObjectsToSeparateFiles.py | 36 ++++ ExportViewportsToImages.py | 41 ++++ ExtendCameraTarget.py | 26 +++ FormatTextAreaSquareMeters.py | 10 + FormatTextAreaSquareMetersWholeNumbers.py | 10 + GetActiveViewportParameters.py | 19 ++ GetAllBlockDefinitionsInDocument.py | 8 + GetAllObjectsNames.py | 10 + GetBlocksName.py | 12 ++ GetBlocksNameSet.py | 11 + GetBlocksOnLayers.py | 28 +++ GetGuid.py | 5 + GetGuidToClipboard.py | 5 + GetLayers.py | 16 ++ GetNameBlocks.py | 16 ++ GetNameSetBlocks.py | 14 ++ GetNames.py | 12 ++ Get_Box_Dims.py | 15 ++ HatchPlanarSrfs-v8.py | 25 +++ HatchPlanarSrfs.py | 25 +++ HideLayerInLayoutDetails.py | 40 ++++ HideLayers.py | 15 ++ HideObjectInLayoutDetails-WORK-IN-PROGRESS.py | 41 ++++ ImportLayers-WIP.py | 12 ++ JJ-LayMCur-Make-Object-Layer-Current.py | 9 + LayoutAddFromClipboard.py | 9 + LayoutCopyToClipboard-WIP.py | 17 ++ LayoutCopyToClipboard.py | 8 + ListAllChangedBlocks.py | 18 ++ Make2D.py | 40 ++++ Make2DBatch-WIP.py | 3 + MergeLayerTrees-2-WORK-IN-PROGRESS.py | 11 + MergeLayerTrees-WORK-IN-PROGRESS.py | 4 + NamedCplaneGUI.py | 10 + NamedLayerFilter.py | 22 ++ NamedViewGUI.py | 9 + NewNamedCplane.py | 9 + ObjectsGroupsToLayers.rvb | 120 +++++++++++ ObjectsToLayerByName.py | 16 ++ ObjectsToLayers.rvb | 53 +++++ OpenBlockWithDefaultApplication.py | 13 ++ OpenBlockWithRhino8WIP.py | 14 ++ ParentLayer.py | 7 + PrintAllAsSeparatePages.py | 56 +++++ PrintAllAsSeparatePagesMultiprocess.py | 90 ++++++++ PrintForFiles-WIP.py | 16 ++ ProximityNetworkCurves-GhPlayer.gh | Bin 0 -> 9186 bytes PullBlocksDown.py | 34 +++ PullBlocksToMeshesDown.py | 10 + PullBlocksToSurfacesDown.py | 10 + QuickExportToDWG-NewScheme.py | 6 + QuickExportToDWG.py | 20 ++ QuickSaveAsToDWG.py | 19 ++ ReMapCamera.py | 35 +++ ReOpenThisFileWithoutSaving.py | 10 + RebuildSurfaceBorder-GhPlayer.gh | Bin 0 -> 7754 bytes RemapCplaneCopyGUI.py | 14 ++ RemapCplaneCopyMultipleGUI.py | 15 ++ RemapCplaneGUI-WIP.py | 9 + RemapCplaneGUI.py | 31 +++ RemapCplaneMultipleGUI.py | 32 +++ RemapView.py | 26 +++ RemapViewGUI.py | 26 +++ ReopenThisFileWithoutSaving-WIP.py | 5 + ReplaceBlockFromFile.py | 19 ++ ResetTransformation.py | 20 ++ Rhino-Aliases.txt | 162 ++++++++++++++ SafeLayout.rhp | Bin 0 -> 41984 bytes SaveAsDWGForFiles.py | 19 ++ ...ockLinked-CANT-FIND-A-WAY-TO-FILTER-OUT.py | 12 ++ SelBlockNames.py | 17 ++ SelClipEnabled.py | 26 +++ SelColorInBlocks.py | 40 ++++ SelEntireObjLayerTree.py | 32 +++ SelHatchPattern-TRY-ME.py | 55 +++++ SelLastN-FINISH-ME.py | 13 ++ SelLayerTree.py | 32 +++ SelMaterialInBlocks.py | 42 ++++ SelObjLayerTree1.py | 31 +++ SelObjLayerTree2.py | 32 +++ SelObjectsLayer-1-mine.py | 16 ++ SelObjectsLayer-2-clement.py | 15 ++ SelParallelPlanes-TEST-ME.py | 37 ++++ SelectByCentralNormal.rvb | 29 +++ SelectObjectLayer.py | 15 ++ SetClippingPlanesName.py | 21 ++ SetLayerColorsToMatchCTB.py | 98 +++++++++ SetLayerColorsToMatchCTBForFiles.py | 20 ++ SetLayerPrintWidthsToMatchCTB.py | 94 ++++++++ SetLayerPrintWidthsToMatchCTBForFiles.py | 20 ++ SetObjectViewportsName.py | 21 ++ SetObjectsName.py | 22 ++ ShowLayerInLayoutDetails.py | 41 ++++ ShowLayers.py | 8 + SwitchView.py | 6 + Tags-ClearTagObjects.py | 12 ++ Tags-SelTagObjects.py | 22 ++ Tags-TagObjects.py | 18 ++ TestMake2D.py | 68 ++++++ UpdateAllChangedBlocks.py | 14 ++ XrefChangePath.py | 27 +++ XrefChangePathList-WIP.py | 15 ++ XrefChangePathWithoutRenaming.py | 25 +++ XrefConvertCurvesToLinesForFiles.py | 16 ++ XrefCreateProxies.py | 15 ++ XrefExportSeparateAsDWG.py | 45 ++++ XrefExportWithModelBasePoint.py | 42 ++++ XrefFilePaths.py | 14 ++ XrefFilePathsSet.py | 17 ++ XrefHide.py | 12 ++ XrefHideBlocks.py | 16 ++ XrefInsertInTheSamePlace.py | 21 ++ XrefLayersHideAndBlocks.py | 17 ++ XrefModifyPath.py | 27 +++ XrefModifyPathList-WIP.py | 15 ++ XrefModifyPathWithoutRenaming.py | 25 +++ XrefModifyUpdateType-without-editing.py | 54 +++++ XrefModifyUpdateType.py | 54 +++++ XrefRemoveDWG.py | 5 + XrefSel.py | 21 ++ XrefSelMultiple.py | 23 ++ XrefShow.py | 11 + XrefShowAll.py | 13 ++ XrefShowBlocks.py | 16 ++ XrefShowLayersAndBlocks.py | 17 ++ XrefToggleVisibility.py | 13 ++ _PrintAllAsSeparatePages.py | 56 +++++ _QuickInsertToAutoCAD.py | 1 + _XrefFilePathSourceV7.py | 15 ++ cplane harvester.gh | Bin 0 -> 9292 bytes diff.gh | Bin 0 -> 6295 bytes ...ll-3dm-rhino-runpythonscript-save-exit.cmd | 1 + jjLayMCur_MakeObjectLayerCurrent.py | 3 + 178 files changed, 4626 insertions(+) create mode 100644 $$/Check if command comes from a plugin - WIP - needs a filter and get all available commands functions.py create mode 100644 $$/DupLayersSublayersAndObjs.py create mode 100644 $$/FlipCamera-NOT-WORKING-DUE-TO-VIEWPORTS-STRETCHING-FRUSTUMS.py create mode 100644 $$/PrintAllAsSeparatePagesMultiprocess-SUPERSEDED.py create mode 100644 $$/RemapCplaneCopyGUI.py create mode 100644 $$/RemapCplaneGUI-WIP.py create mode 100644 $$/RemapCplaneGUI.py create mode 100644 $$/ReopenThisFileWithoutSaving-WIP.py create mode 100644 $$/SelColorOnlyInBlocks.py create mode 100644 $$/SelLayerByObject-BUMMER-DOESNT-SELECT-MULTIPLE-LAYERS-USE-SELLAYER-INSTEAD.py create mode 100644 $$/SelLayerByObject-GOT-A-BIT-CONFUSED-HERE.py create mode 100644 $$/SelMaterialOnlyInBlocks.py create mode 100644 $$/SelectAllObjsOnObjLayers.py create mode 100644 $$/SetAllLayerPrintWidths-Chetwoods-Standard-ctb-TOO-SLOW.py create mode 100644 $$/ShowSelectedByMatchingLayer.py create mode 100644 $$/_PrintAllAsSeparatePages.py create mode 100644 $$/pywin32-conenct-to-a-running-Rhino-process.py create mode 100644 1Layout1PDF.py create mode 100644 AbsoluteTolerance.py create mode 100644 AcadIntegration.py create mode 100644 ActivateDetailViewsonLayouts-WORK-IN-PROGRESS.py create mode 100644 BatchMake2D-NOT-WORKING-FOR-LINKED-BLOCKS-AND-CLIPPING-PLANES.py create mode 100644 BatchMake2D.py create mode 100644 BlockTools 1.4.rhi create mode 100644 BlockUpdate.py create mode 100644 BlockUpdateSelected-NOT-WORKING-MISSING-UPDATE-OPTION.py create mode 100644 ChangeCameraProjection.py create mode 100644 ChangeLayerInBlockRecursively.py create mode 100644 ChangeMaterial.py create mode 100644 ChangeMaterialForAll.py create mode 100644 ClipEnableGUI.py create mode 100644 ClipSelGUI.py create mode 100644 ClipSelGUIMultiple.py create mode 100644 ConsolidateLayers.py create mode 100644 ConvertHatchesToSrfs_cmd.py create mode 100644 ConvertPlanarSrfsToHatch-v8.py create mode 100644 ConvertPlanarSrfsToHatch.py create mode 100644 ConvertProjectV8ToV7.py create mode 100644 ConvertV8ToV7ForFiles.py create mode 100644 DeleteBlock.py create mode 100644 DeleteNamedCplane.py create mode 100644 DisableAllClippingPlanes.py create mode 100644 EtoForm_MultipleListBox_PrintAllBlockDefinitionsInDocument.py create mode 100644 EtoForm_MultipleListBox_PrintSelectedLayerName.py create mode 100644 ExportDwgSchemeRGBColors.py create mode 100644 ExportObjectsToSeparateFiles.py create mode 100644 ExportViewportsToImages.py create mode 100644 ExtendCameraTarget.py create mode 100644 FormatTextAreaSquareMeters.py create mode 100644 FormatTextAreaSquareMetersWholeNumbers.py create mode 100644 GetActiveViewportParameters.py create mode 100644 GetAllBlockDefinitionsInDocument.py create mode 100644 GetAllObjectsNames.py create mode 100644 GetBlocksName.py create mode 100644 GetBlocksNameSet.py create mode 100644 GetBlocksOnLayers.py create mode 100644 GetGuid.py create mode 100644 GetGuidToClipboard.py create mode 100644 GetLayers.py create mode 100644 GetNameBlocks.py create mode 100644 GetNameSetBlocks.py create mode 100644 GetNames.py create mode 100644 Get_Box_Dims.py create mode 100644 HatchPlanarSrfs-v8.py create mode 100644 HatchPlanarSrfs.py create mode 100644 HideLayerInLayoutDetails.py create mode 100644 HideLayers.py create mode 100644 HideObjectInLayoutDetails-WORK-IN-PROGRESS.py create mode 100644 ImportLayers-WIP.py create mode 100644 JJ-LayMCur-Make-Object-Layer-Current.py create mode 100644 LayoutAddFromClipboard.py create mode 100644 LayoutCopyToClipboard-WIP.py create mode 100644 LayoutCopyToClipboard.py create mode 100644 ListAllChangedBlocks.py create mode 100644 Make2D.py create mode 100644 Make2DBatch-WIP.py create mode 100644 MergeLayerTrees-2-WORK-IN-PROGRESS.py create mode 100644 MergeLayerTrees-WORK-IN-PROGRESS.py create mode 100644 NamedCplaneGUI.py create mode 100644 NamedLayerFilter.py create mode 100644 NamedViewGUI.py create mode 100644 NewNamedCplane.py create mode 100644 ObjectsGroupsToLayers.rvb create mode 100644 ObjectsToLayerByName.py create mode 100644 ObjectsToLayers.rvb create mode 100644 OpenBlockWithDefaultApplication.py create mode 100644 OpenBlockWithRhino8WIP.py create mode 100644 ParentLayer.py create mode 100644 PrintAllAsSeparatePages.py create mode 100644 PrintAllAsSeparatePagesMultiprocess.py create mode 100644 PrintForFiles-WIP.py create mode 100644 ProximityNetworkCurves-GhPlayer.gh create mode 100644 PullBlocksDown.py create mode 100644 PullBlocksToMeshesDown.py create mode 100644 PullBlocksToSurfacesDown.py create mode 100644 QuickExportToDWG-NewScheme.py create mode 100644 QuickExportToDWG.py create mode 100644 QuickSaveAsToDWG.py create mode 100644 ReMapCamera.py create mode 100644 ReOpenThisFileWithoutSaving.py create mode 100644 RebuildSurfaceBorder-GhPlayer.gh create mode 100644 RemapCplaneCopyGUI.py create mode 100644 RemapCplaneCopyMultipleGUI.py create mode 100644 RemapCplaneGUI-WIP.py create mode 100644 RemapCplaneGUI.py create mode 100644 RemapCplaneMultipleGUI.py create mode 100644 RemapView.py create mode 100644 RemapViewGUI.py create mode 100644 ReopenThisFileWithoutSaving-WIP.py create mode 100644 ReplaceBlockFromFile.py create mode 100644 ResetTransformation.py create mode 100644 Rhino-Aliases.txt create mode 100644 SafeLayout.rhp create mode 100644 SaveAsDWGForFiles.py create mode 100644 SelBlockLinked-CANT-FIND-A-WAY-TO-FILTER-OUT.py create mode 100644 SelBlockNames.py create mode 100644 SelClipEnabled.py create mode 100644 SelColorInBlocks.py create mode 100644 SelEntireObjLayerTree.py create mode 100644 SelHatchPattern-TRY-ME.py create mode 100644 SelLastN-FINISH-ME.py create mode 100644 SelLayerTree.py create mode 100644 SelMaterialInBlocks.py create mode 100644 SelObjLayerTree1.py create mode 100644 SelObjLayerTree2.py create mode 100644 SelObjectsLayer-1-mine.py create mode 100644 SelObjectsLayer-2-clement.py create mode 100644 SelParallelPlanes-TEST-ME.py create mode 100644 SelectByCentralNormal.rvb create mode 100644 SelectObjectLayer.py create mode 100644 SetClippingPlanesName.py create mode 100644 SetLayerColorsToMatchCTB.py create mode 100644 SetLayerColorsToMatchCTBForFiles.py create mode 100644 SetLayerPrintWidthsToMatchCTB.py create mode 100644 SetLayerPrintWidthsToMatchCTBForFiles.py create mode 100644 SetObjectViewportsName.py create mode 100644 SetObjectsName.py create mode 100644 ShowLayerInLayoutDetails.py create mode 100644 ShowLayers.py create mode 100644 SwitchView.py create mode 100644 Tags-ClearTagObjects.py create mode 100644 Tags-SelTagObjects.py create mode 100644 Tags-TagObjects.py create mode 100644 TestMake2D.py create mode 100644 UpdateAllChangedBlocks.py create mode 100644 XrefChangePath.py create mode 100644 XrefChangePathList-WIP.py create mode 100644 XrefChangePathWithoutRenaming.py create mode 100644 XrefConvertCurvesToLinesForFiles.py create mode 100644 XrefCreateProxies.py create mode 100644 XrefExportSeparateAsDWG.py create mode 100644 XrefExportWithModelBasePoint.py create mode 100644 XrefFilePaths.py create mode 100644 XrefFilePathsSet.py create mode 100644 XrefHide.py create mode 100644 XrefHideBlocks.py create mode 100644 XrefInsertInTheSamePlace.py create mode 100644 XrefLayersHideAndBlocks.py create mode 100644 XrefModifyPath.py create mode 100644 XrefModifyPathList-WIP.py create mode 100644 XrefModifyPathWithoutRenaming.py create mode 100644 XrefModifyUpdateType-without-editing.py create mode 100644 XrefModifyUpdateType.py create mode 100644 XrefRemoveDWG.py create mode 100644 XrefSel.py create mode 100644 XrefSelMultiple.py create mode 100644 XrefShow.py create mode 100644 XrefShowAll.py create mode 100644 XrefShowBlocks.py create mode 100644 XrefShowLayersAndBlocks.py create mode 100644 XrefToggleVisibility.py create mode 100644 _PrintAllAsSeparatePages.py create mode 100644 _QuickInsertToAutoCAD.py create mode 100644 _XrefFilePathSourceV7.py create mode 100644 cplane harvester.gh create mode 100644 diff.gh create mode 100644 for-all-3dm-rhino-runpythonscript-save-exit.cmd create mode 100644 jjLayMCur_MakeObjectLayerCurrent.py diff --git a/$$/Check if command comes from a plugin - WIP - needs a filter and get all available commands functions.py b/$$/Check if command comes from a plugin - WIP - needs a filter and get all available commands functions.py new file mode 100644 index 0000000..9a5ca96 --- /dev/null +++ b/$$/Check if command comes from a plugin - WIP - needs a filter and get all available commands functions.py @@ -0,0 +1,17 @@ +import Rhino.PlugIns as rp +import rhinoscriptsyntax as rs + +pl_cmd = dict() +query_string = rs.GetString(message="name of the command") + +for plkv in rp.PlugIn.GetInstalledPlugIns(): + guid = plkv.Key + name = plkv.Value + pl_info = rp.PlugIn.GetPlugInInfo(guid) + pl_cmd[name] = [cmd for cmd in pl_info.CommandNames] + +for pl in pl_cmd: + for pl_com + if query_string in pl: + print pl + print "\t" + str(pl_cmd[pl]) diff --git a/$$/DupLayersSublayersAndObjs.py b/$$/DupLayersSublayersAndObjs.py new file mode 100644 index 0000000..2b7aada --- /dev/null +++ b/$$/DupLayersSublayersAndObjs.py @@ -0,0 +1,52 @@ +"""Duplicates a layer and all its sublayers incuding objects +Script by Mitch Heynick 20 April 2014""" + +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def CopyObjectsToLayer(objs,layer): + copies=rs.CopyObjects(objs) + rs.ObjectLayer(copies,layer) + +def UniqueLayerCopyName(layer,top): + #Extract main level name; add - Copy to top level layer name only + layers=rs.LayerNames() + nameList=layer.split("::") + newName=nameList[-1] + if top: newName+=" - Copy" + if newName in layers: + i=0 + while True: + i+=1 + testName=newName+"({})".format(i) + if not testName in layers: return testName + return newName + +def DupAllSubLayers(layer,layerCopy): + subs=rs.LayerChildren(layer) + if subs: + for sub in subs: + color=rs.LayerColor(sub) + objs=rs.ObjectsByLayer(sub) + name=UniqueLayerCopyName(sub,False) + addLayer=rs.AddLayer(name,color,parent=layerCopy) + CopyObjectsToLayer(objs,addLayer) + rs.ExpandLayer(addLayer,rs.IsLayerExpanded(sub)) + DupAllSubLayers(sub,addLayer) + +def DupLayersSublayersAndObjs(): + layer=rs.GetLayer() + if layer==None: return + #do initial run with selected layer + color=rs.LayerColor(layer) + objs=rs.ObjectsByLayer(layer) + parentLayer=rs.ParentLayer(layer) + + + copyName=UniqueLayerCopyName(layer,True) + layerCopy=rs.AddLayer(copyName,color,parent=parentLayer) + CopyObjectsToLayer(objs,layerCopy) + rs.ExpandLayer(layerCopy,rs.IsLayerExpanded(layer)) + DupAllSubLayers(layer,layerCopy) + +DupLayersSublayersAndObjs() \ No newline at end of file diff --git a/$$/FlipCamera-NOT-WORKING-DUE-TO-VIEWPORTS-STRETCHING-FRUSTUMS.py b/$$/FlipCamera-NOT-WORKING-DUE-TO-VIEWPORTS-STRETCHING-FRUSTUMS.py new file mode 100644 index 0000000..033346e --- /dev/null +++ b/$$/FlipCamera-NOT-WORKING-DUE-TO-VIEWPORTS-STRETCHING-FRUSTUMS.py @@ -0,0 +1,14 @@ + +import scriptcontext as sc + +vp = sc.doc.Views.ActiveView.ActiveViewport +p1 = vp.CameraLocation +p2 = vp.CameraTarget +vecDir = p2-p1 +p1 = p1 + (vecDir*2) +vecDir.Reverse() + +vp.SetCameraLocations(p2, p1) +sc.doc.Views.Redraw() + + \ No newline at end of file diff --git a/$$/PrintAllAsSeparatePagesMultiprocess-SUPERSEDED.py b/$$/PrintAllAsSeparatePagesMultiprocess-SUPERSEDED.py new file mode 100644 index 0000000..66fe85e --- /dev/null +++ b/$$/PrintAllAsSeparatePagesMultiprocess-SUPERSEDED.py @@ -0,0 +1,8 @@ +import os +import subprocess +import rhinoscriptsyntax as rs + +with open(os.environ['TEMP'] + "\\printing-madness" + ".cmd", "w") as madness: + madness.write('start /min "" "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\_PrintAllAsSeparatePages.py) -Exit No" ' + chr(34) + rs.DocumentPath() + "\\" + rs.DocumentName() + chr(34)) + madness.flush() + subprocess.Popen(madness.name, shell=True) \ No newline at end of file diff --git a/$$/RemapCplaneCopyGUI.py b/$$/RemapCplaneCopyGUI.py new file mode 100644 index 0000000..b50329d --- /dev/null +++ b/$$/RemapCplaneCopyGUI.py @@ -0,0 +1,31 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +#doesn't work when this section turned on - try using transforms instead: + +#selected_obj = rs.coercerhinoobject(rs.GetObject(preselect=True)) +#if str(selected_obj.ObjectType) == "InstanceReference": +# selected_obj_name = selected_obj.InstanceDefinition.Name +#else: +# selected_obj_name = "" + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplane_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + + +#doesn't work when this section turned on - try using transforms instead: +#message_from = "Name: " + selected_obj_name + "\n" + "Cplane to Map from" +#message_to = "Name: " + selected_obj_name + "\n" + "Cplane to Map to" + +#selected_cplane_from = rs.ComboListBox(sorted(named_cplanes), message=message_from) +#selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), message=message_to) + + +current_cplane = rs.ViewCPlane() +rs.RestoreNamedCPlane(selected_cplane_from) + +rs.Command("RemapCplane Copy=Yes Cplane " + chr(34) + selected_cplane_to + chr(34)) + +#restore previous Cplane +rs.ViewCPlane(plane=current_cplane) \ No newline at end of file diff --git a/$$/RemapCplaneGUI-WIP.py b/$$/RemapCplaneGUI-WIP.py new file mode 100644 index 0000000..5261fc7 --- /dev/null +++ b/$$/RemapCplaneGUI-WIP.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplane_to = rs.ComboListBox(named_cplanes, "Cplane to Map to") +selected_cplane_from = rs.ComboListBox(named_cplanes, "Cplane to Map from") + +rs.ViewCPlane(plane=selected_cplane_to) +rs.Command("RemapCplane Cplane " + selected_cplane) \ No newline at end of file diff --git a/$$/RemapCplaneGUI.py b/$$/RemapCplaneGUI.py new file mode 100644 index 0000000..98e8dc0 --- /dev/null +++ b/$$/RemapCplaneGUI.py @@ -0,0 +1,15 @@ +# needs a FROM Cplane - could use NamedCplaneGUI.py + +import rhinoscriptsyntax as rs +import scriptcontext as sc + +#world_top_cplane = rs.PlaneFromPoints("0,0,0", "1,0,0", "0,1,0") + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + +#rs.coerceplane() + +#rs.ViewCPlane(plane=world_top_cplane) +rs.Command("RemapCplane Cplane " + chr(34) + selected_cplane_to + chr(34)) +#rs.Command("Cplane Undo Enter") \ No newline at end of file diff --git a/$$/ReopenThisFileWithoutSaving-WIP.py b/$$/ReopenThisFileWithoutSaving-WIP.py new file mode 100644 index 0000000..86767c2 --- /dev/null +++ b/$$/ReopenThisFileWithoutSaving-WIP.py @@ -0,0 +1,5 @@ +# can't get it to work when file isn't saved, below commands return None +import rhinoscriptsyntax as rs + +document_location = rs.DocumentPath() + rs.DocumentName() +rs.Command("Open No " + chr(34) + document_location + chr(34)) \ No newline at end of file diff --git a/$$/SelColorOnlyInBlocks.py b/$$/SelColorOnlyInBlocks.py new file mode 100644 index 0000000..e4f98e0 --- /dev/null +++ b/$$/SelColorOnlyInBlocks.py @@ -0,0 +1,38 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +selected_colors = list() + +# get colors of blocks' sub-objects +# looping through all objects due to: https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/12 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + sub_object_ids = object.GetSelectedSubObjects() + if sub_object_ids: + for sub_object_id in sub_object_ids: + sub_object = object.InstanceDefinition.GetObjects()[sub_object_id.Index] + sub_object_color = sub_object.Attributes.DrawColor(sc.doc) + selected_colors.append(sub_object_color) + +# get colors of other objects +for object_id in rs.SelectedObjects(): + object = rs.coercerhinoobject(object_id) + object_color = object.Attributes.DrawColor(sc.doc) + selected_colors.append(object_color) + +def _SelColor(object): + for sub_object_id, sub_object in enumerate(object.InstanceDefinition.GetObjects()): + if type(sub_object) == Rhino.DocObjects.InstanceObject: + _SelColor(sub_object) + if sub_object.Attributes.DrawColor(sc.doc) in selected_colors: + object.SelectSubObject(Rhino.Geometry.ComponentIndex(Rhino.Geometry.ComponentIndexType.InstanceDefinitionPart, sub_object_id), True, True, True) + +# select objects by color recursively, even though doesn't work for nested blocks +# https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/13 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + _SelColor(object) + +rs.EnableRedraw() +rs.Redraw() diff --git a/$$/SelLayerByObject-BUMMER-DOESNT-SELECT-MULTIPLE-LAYERS-USE-SELLAYER-INSTEAD.py b/$$/SelLayerByObject-BUMMER-DOESNT-SELECT-MULTIPLE-LAYERS-USE-SELLAYER-INSTEAD.py new file mode 100644 index 0000000..29d70af --- /dev/null +++ b/$$/SelLayerByObject-BUMMER-DOESNT-SELECT-MULTIPLE-LAYERS-USE-SELLAYER-INSTEAD.py @@ -0,0 +1,11 @@ +import scriptcontext as sc +import rhinoscriptsyntax as rs + +object_ids = rs.GetObjects(preselect=True) + +if object_ids: + object_layers = [] + for object_id in object_ids: + object_layers.append(rs.ObjectLayer(object_id)) + + rs.ObjectsByLayer(object_layers) \ No newline at end of file diff --git a/$$/SelLayerByObject-GOT-A-BIT-CONFUSED-HERE.py b/$$/SelLayerByObject-GOT-A-BIT-CONFUSED-HERE.py new file mode 100644 index 0000000..64a4926 --- /dev/null +++ b/$$/SelLayerByObject-GOT-A-BIT-CONFUSED-HERE.py @@ -0,0 +1,15 @@ +import scriptcontext as sc +import rhinoscriptsyntax as rs + +object_id = rs.GetObject(preselect=True) +object_layer = rs.ObjectLayer(object_id) +a=rs.ObjectsByLayer(object_layer) +a + +#this won't work - rs.ObjectsByLayer doesn't accept lists +#if object_ids: +# object_layers = [] +# for object_id in object_ids: +# object_layers.append(rs.ObjectLayer(object_id)) +# +# rs.ObjectsByLayer(object_layers) \ No newline at end of file diff --git a/$$/SelMaterialOnlyInBlocks.py b/$$/SelMaterialOnlyInBlocks.py new file mode 100644 index 0000000..4c8449a --- /dev/null +++ b/$$/SelMaterialOnlyInBlocks.py @@ -0,0 +1,40 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +selected_materials = list() + +# get materials of blocks' sub-objects +# looping through all objects due to: https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/12 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + sub_object_ids = object.GetSelectedSubObjects() + if sub_object_ids: + for sub_object_id in sub_object_ids: + sub_object = object.InstanceDefinition.GetObjects()[sub_object_id.Index] + if sub_object.RenderMaterial: + sub_object_material = sub_object.RenderMaterial.Id + selected_materials.append(sub_object_material) + +# get materials of other objects +for object_id in rs.SelectedObjects(): + object = rs.coercerhinoobject(object_id) + if object.RenderMaterial: + object_material = object.RenderMaterial.Id + selected_materials.append(object_material) + +def _SelMaterial(object): + for sub_object_id, sub_object in enumerate(object.InstanceDefinition.GetObjects()): + if type(sub_object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(sub_object) + if sub_object.RenderMaterial and sub_object.RenderMaterial.Id in selected_materials: + object.SelectSubObject(Rhino.Geometry.ComponentIndex(Rhino.Geometry.ComponentIndexType.InstanceDefinitionPart, sub_object_id), True, True, True) + +# select objects by material recursively, even though doesn't work for nested blocks +# https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/13 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(object) + +rs.EnableRedraw() +rs.Redraw() diff --git a/$$/SelectAllObjsOnObjLayers.py b/$$/SelectAllObjsOnObjLayers.py new file mode 100644 index 0000000..d269640 --- /dev/null +++ b/$$/SelectAllObjsOnObjLayers.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs + +def SelectAllObjsOnObjLayers(): + objs=rs.GetObjects("Select objects",preselect=True) + if not objs: return + rs.EnableRedraw(False) + layers=[rs.ObjectLayer(obj) for obj in objs] + for layer in layers: rs.ObjectsByLayer(layer,True) +SelectAllObjsOnObjLayers() \ No newline at end of file diff --git a/$$/SetAllLayerPrintWidths-Chetwoods-Standard-ctb-TOO-SLOW.py b/$$/SetAllLayerPrintWidths-Chetwoods-Standard-ctb-TOO-SLOW.py new file mode 100644 index 0000000..688405c --- /dev/null +++ b/$$/SetAllLayerPrintWidths-Chetwoods-Standard-ctb-TOO-SLOW.py @@ -0,0 +1,93 @@ +import rhinoscriptsyntax as rs +import re + +#find layers that have one of the codes in the name +layers = [layer for layer in rs.LayerNames() if ">" not in layer and + re.search("AR[0-9]+", layer)] + +def SetAllLayerPrintWidths(): + for layer in layers: + [rs.LayerPrintWidth(layer, width=v) for k, v in ctb_printwidths.items() + if k in layer] + +#codes extracted from template files +ctb_printwidths={ +"AR000": 0.05, +"AR001": 0.05, +"AR002": 0.05, +"AR003": 0.1, +"AR004": 0.05, +"AR006": 0.05, +"AR007": 0.18, +"AR008": 0.05, +"AR009": 0.05, +"AR031": 0.1, +"AR035": 0.05, +"AR036": 0.05, +"AR042": 0.05, +"AR061": 0.05, +"AR062": 0.05, +"AR063": 0.05, +"AR070": 0.1, +"AR071": 0.05, +"AR075": 0.05, +"AR169": 0.1, +"AR211": 0.18, +"AR214": 0.1, +"AR216": 0.15, +"AR219": 0.1, +"AR221": 0.18, +"AR229": 0.05, +"AR231": 0.05, +"AR232": 0.25, +"AR237": 0.18, +"AR240": 0.15, +"AR241": 0.15, +"AR272": 0.18, +"AR277": 0.15, +"AR281": 0.18, +"AR282": 0.15, +"AR283": 0.15, +"AR310": 0.05, +"AR314": 0.1, +"AR315": 0.15, +"AR318": 0.1, +"AR319": 0.25, +"AR324": 0.15, +"AR325": 0.15, +"AR340": 0.1, +"AR351": 0.15, +"AR371": 0.15, +"AR413": 0.18, +"AR414": 0.1, +"AR420": 0.15, +"AR431": 0.05, +"AR439": 0.15, +"AR471": 0.05, +"AR520": 0.05, +"AR522": 0.05, +"AR525": 0.18, +"AR610": 0.18, +"AR611": 0.1, +"AR630": 0.1, +"AR640": 0.05, +"AR661": 0.15, +"AR664": 0.1, +"AR680": 0.05, +"AR683": 0.1, +"AR711": 0.1, +"AR731": 0.1, +"AR741": 0.05, +"AR783": 0.1, +"AR785": 0.05, +"AR900": 0.25, +"AR901": 0.05, +"AR902": 0.05, +"AR904": 0.05, +"AR905": 0.05, +"AR906": 0.05, +"AR907": 0.1, +"AR908": 0.1, +"AR910": 0.05} + +SetAllLayerPrintWidths() diff --git a/$$/ShowSelectedByMatchingLayer.py b/$$/ShowSelectedByMatchingLayer.py new file mode 100644 index 0000000..daefc92 --- /dev/null +++ b/$$/ShowSelectedByMatchingLayer.py @@ -0,0 +1,37 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc +import System + +def ShowSelectedByMatchingLayers(): + + hIds = rs.HiddenObjects() + if not hIds: + print "No objects are hidden." + return + + selIds = rs.SelectedObjects() + + if not selIds: + selIds = rs.GetObjects("Select objects on the layers to match.") + if not selIds:return + + allIds = rs.AllObjects() + if not allIds: return + + offLayers = [] + lockedLayers = [] + selLayers = list(set([System.Guid((rs.LayerId(rs.ObjectLayer(id)))) for id in selIds])) + + rs.EnableRedraw(False) + for id in allIds: + obj = sc.doc.Objects.Find(id) + if obj.IsHidden: + idx = obj.Attributes.LayerIndex + layerId = sc.doc.Layers.FindIndex(idx).Id + if layerId in selLayers: + rs.ShowObject(id) + + rs.EnableRedraw(True) + +if __name__ == "__main__": ShowSelectedByMatchingLayers() \ No newline at end of file diff --git a/$$/_PrintAllAsSeparatePages.py b/$$/_PrintAllAsSeparatePages.py new file mode 100644 index 0000000..44a4bbc --- /dev/null +++ b/$$/_PrintAllAsSeparatePages.py @@ -0,0 +1,56 @@ +import Rhino +import scriptcontext as sc +import System.Drawing +import rhinoscriptsyntax as rs +import os + +folder = os.getcwd() +titleblock = dict() + +def createSinglePDF(view, titleblock): + pdf = Rhino.FileIO.FilePdf.Create() + dpi = 300 + settings = Rhino.Display.ViewCaptureSettings(view, dpi) + settings.OutputColor = Rhino.Display.ViewCaptureSettings.ColorMode.DisplayColor + settings.DefaultPrintWidthMillimeters = 0.18 + pdf.AddPage(settings) + filename = folder + os.path.sep + titleblock.get("project_number","0000") + "-" + \ + titleblock.get("originator", "00") + "-" + \ + titleblock.get("zone", "00") + "-" + \ + titleblock.get("level", "00") + "-" + \ + titleblock.get("drawing_type", "00") + "-" + \ + titleblock.get("role", "0") + "-" + \ + titleblock.get("drawing_number", "00000") + "_" + \ + titleblock.get("latest_revision", "00") + " " + \ + titleblock.get("drawing_title_1", "000000000") + " " + \ + titleblock.get("drawing_title_2", "") + " " + \ + titleblock.get("drawing_title_3", "") + ".pdf" + pdf.Write(filename) + +for view in sc.doc.Views.GetPageViews(): + for object in sc.doc.Objects.FindByLayer("titleblock index-AR002"): + if type(object) == Rhino.DocObjects.TextObject and \ + view.ActiveViewportID == object.Attributes.ViewportId: + if object.Name == "Project Number": + titleblock["project_number"] = object.DisplayText + if object.Name == "Originator": + titleblock["originator"] = object.DisplayText + if object.Name == "Zone": + titleblock["zone"] = object.DisplayText + if object.Name == "Level": + titleblock["level"] = object.DisplayText + if object.Name == "Drawing Type": + titleblock["drawing_type"] = object.DisplayText + if object.Name == "Role": + titleblock["role"] = object.DisplayText + if object.Name == "Drawing Number": + titleblock["drawing_number"] = object.DisplayText + if object.Name == "Latest Revision": + titleblock["latest_revision"] = object.DisplayText + if object.Name == "Drawing Title 1": + titleblock["drawing_title_1"] = object.DisplayText + if object.Name == "Drawing Title 2": + titleblock["drawing_title_2"] = object.DisplayText + if object.Name == "Drawing Title 3": + titleblock["drawing_title_3"] = object.DisplayText + createSinglePDF(view, titleblock) \ No newline at end of file diff --git a/$$/pywin32-conenct-to-a-running-Rhino-process.py b/$$/pywin32-conenct-to-a-running-Rhino-process.py new file mode 100644 index 0000000..160481c --- /dev/null +++ b/$$/pywin32-conenct-to-a-running-Rhino-process.py @@ -0,0 +1,6 @@ +import win32com.client as win32 + +a = win32.Dispatch("Rhino.Interface") +b=a.IsInitialized +c=a.BringToTop() +d=a.Visible \ No newline at end of file diff --git a/1Layout1PDF.py b/1Layout1PDF.py new file mode 100644 index 0000000..ff22d5b --- /dev/null +++ b/1Layout1PDF.py @@ -0,0 +1,21 @@ +import Rhino +import scriptcontext as sc +import System.Drawing +import rhinoscriptsyntax as rs + +def createSinglePDF(view): + folder = rs.BrowseForFolder() + prefix = "PREFIX" + folder += "\\" + prefix + pdf = Rhino.FileIO.FilePdf.Create() + dpi = 300 +# size = System.Drawing.Size(8.5*dpi,11*dpi) + settings = Rhino.Display.ViewCaptureSettings(view, dpi) + pdf.AddPage(settings) + filename = folder+view.PageName+'.pdf' + pdf.Write(filename) + + +for i in sc.doc.Views: + if type(i) is Rhino.Display.RhinoPageView: + createSinglePDF(i) diff --git a/AbsoluteTolerance.py b/AbsoluteTolerance.py new file mode 100644 index 0000000..7814fb0 --- /dev/null +++ b/AbsoluteTolerance.py @@ -0,0 +1,11 @@ +from rhinoscriptsyntax import UnitAbsoluteTolerance, ComboListBox + +def AbsoluteTolerance(): + selected_tolerance = ComboListBox([100,10,1,0.1,0.01,0.001,0.0001], + message="Choose Absolute Tolerace", + title="Absolute Tolerace") + if selected_tolerance == None: + return + UnitAbsoluteTolerance(float(selected_tolerance)) + +AbsoluteTolerance() \ No newline at end of file diff --git a/AcadIntegration.py b/AcadIntegration.py new file mode 100644 index 0000000..e3fbad5 --- /dev/null +++ b/AcadIntegration.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs +from datetime import datetime +import os + +buffer_folder = rs.GetDocumentData("ACAD_Exports", "Folder") +if buffer_folder is None: + buffer_folder = rs.BrowseForFolder() + rs.SetDocumentData("ACAD_Exports", "Folder", buffer_folder) + +file_name = buffer_folder + os.path.sep + \ +datetime.utcnow().strftime('%Y-%m-%d-%H-%M-%S-%f')[:-3] + "-" + \ +rs.DocumentName() + ".dwg" + +rs.Command("-_Export " + chr(34) + file_name + chr(34)) + diff --git a/ActivateDetailViewsonLayouts-WORK-IN-PROGRESS.py b/ActivateDetailViewsonLayouts-WORK-IN-PROGRESS.py new file mode 100644 index 0000000..c379200 --- /dev/null +++ b/ActivateDetailViewsonLayouts-WORK-IN-PROGRESS.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +strLayout = rs.CurrentView() +aDetails = sc.doc.Views.GetPageViews()[2].GetDetailViews() + +for i in aDetails: + rs.CurrentDetail("05047", detail=i.Id) + diff --git a/BatchMake2D-NOT-WORKING-FOR-LINKED-BLOCKS-AND-CLIPPING-PLANES.py b/BatchMake2D-NOT-WORKING-FOR-LINKED-BLOCKS-AND-CLIPPING-PLANES.py new file mode 100644 index 0000000..104a11a --- /dev/null +++ b/BatchMake2D-NOT-WORKING-FOR-LINKED-BLOCKS-AND-CLIPPING-PLANES.py @@ -0,0 +1,78 @@ +import Rhino.Geometry +from Rhino.DocObjects import ObjectType +from Rhino.Display import RhinoPageView +import scriptcontext as sc +import rhinoscriptsyntax as rs + +def BatchMake2D(): + selected_page_names = rs.MultiListBox([i.PageName for i in sc.doc.Views.GetPageViews()]) + if selected_page_names == None: + return + selected_pages = [i for i in sc.doc.Views.GetPageViews() if i.PageName in selected_page_names] + + for selected_page in selected_pages: + detail_views = RhinoPageView.GetDetailViews(selected_page) + + cgeo_views = [detail_view for detail_view in detail_views if detail_view.Name and "CGeo" in detail_view.Name] + if len(cgeo_views) == 0: + rs.MessageBox("No '-CGeo' viewports found.\nAdd corresponding named viewports.\nBatch Make2D will exit now.") + return + + for detail_view in detail_views: + if detail_view.Name == None: + continue + if "CGeo" in detail_view.Name: + continue + + first_corner = Rhino.Geometry.Point2d(detail_view.Viewport.Bounds.Left, detail_view.Viewport.Bounds.Bottom) + second_corner = Rhino.Geometry.Point2d(detail_view.Viewport.Bounds.Right, detail_view.Viewport.Bounds.Top) + + detail_view.IsActive = True + + rhino_objects = sc.doc.Objects.FindByCrossingWindowRegion(detail_view.Viewport, + first_corner, second_corner, + True, ObjectType.AnyObject) + + parameters = Rhino.Geometry.HiddenLineDrawingParameters() + parameters.AbsoluteTolerance = sc.doc.ModelAbsoluteTolerance + parameters.Flatten = True + parameters.IncludeHiddenCurves = False + parameters.IncludeTangentEdges = False + parameters.IncludeTangentSeams = False + parameters.SetViewport(detail_view.Viewport) + for obj in rhino_objects: + parameters.AddGeometry(obj.Geometry, obj.Id) + + for vp in detail_views: + if vp.Name and detail_view.Name in vp.Name and "CGeo" in vp.Name: + cgeo_viewport = vp.Viewport + break + else: + cgeo_viewport = None + + if cgeo_viewport == None: + continue + + cgeo_viewport_plane = Rhino.Geometry.Plane(cgeo_viewport.CameraTarget, + cgeo_viewport.CameraX, + cgeo_viewport.CameraY) + xform = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY, cgeo_viewport_plane) + + hld = Rhino.Geometry.HiddenLineDrawing.Compute(parameters, True) + + for hld_curve in hld.Segments: + if not hld_curve: + continue + if not hld_curve.ParentCurve: + continue + if hld_curve.ParentCurve.SilhouetteType == Rhino.Geometry.SilhouetteType.None: + continue + if hld_curve.SegmentVisibility == Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Visible: + source_obj_attribs = rs.coercerhinoobject(hld_curve.ParentCurve.SourceObject.Tag).Attributes + curve = hld_curve.CurveGeometry.DuplicateCurve() + curve.Transform(xform) + sc.doc.Objects.AddCurve(curve, source_obj_attribs) + + sc.doc.Views.Redraw() + +BatchMake2D() \ No newline at end of file diff --git a/BatchMake2D.py b/BatchMake2D.py new file mode 100644 index 0000000..2b25cff --- /dev/null +++ b/BatchMake2D.py @@ -0,0 +1,70 @@ +import Rhino.Geometry +from Rhino.DocObjects import ObjectType +from Rhino.Display import RhinoPageView +import scriptcontext as sc +import rhinoscriptsyntax as rs + +def BatchMake2D(): + selected_page_names = rs.MultiListBox([i.PageName for i in sc.doc.Views.GetPageViews()]) + if selected_page_names == None: + return + selected_pages = [i for i in sc.doc.Views.GetPageViews() if i.PageName in selected_page_names] + + for selected_page in selected_pages: + all_detail_views = RhinoPageView.GetDetailViews(selected_page) + + #select views by "CGeo" in the name + #in the future autogenerate corresponding views based on geolocation (EarthAnchorPoint) + target_views = [detail_view for detail_view in all_detail_views if detail_view.Name and "CGeo" in detail_view.Name] + if len(target_views) == 0: + rs.MessageBox("No '-CGeo' viewports found.\nAdd corresponding named viewports.\nBatch Make2D will exit now.") + return + + for source_view in all_detail_views: + if source_view.Name == None: + continue + if "CGeo" in source_view.Name: + continue + + first_corner = Rhino.Geometry.Point2d(source_view.Viewport.Bounds.Left, source_view.Viewport.Bounds.Bottom) + second_corner = Rhino.Geometry.Point2d(source_view.Viewport.Bounds.Right, source_view.Viewport.Bounds.Top) + + + for vp in all_detail_views: + if vp.Name and source_view.Name in vp.Name and "CGeo" in vp.Name: + target_viewport = vp.Viewport + break + else: + target_viewport = None + if target_viewport == None: + continue + + source_view.IsActive = True + + sc.doc.Objects.UnselectAll() + #https://discourse.mcneel.com/t/how-to-get-coordinates-of-a-viewport-corners/153493 + rhino_objects = sc.doc.Objects.FindByCrossingWindowRegion(source_view.Viewport, + first_corner, second_corner, + True, ObjectType.AnyObject) + rs.SelectObjects(rhino_objects) + + #transform Make2D results to the correct location (based on chosen real-world "geolocation") + source_viewport_plane = Rhino.Geometry.Plane(source_view.Viewport.CameraTarget, + source_view.Viewport.CameraX, + source_view.Viewport.CameraY) + target_viewport_plane = Rhino.Geometry.Plane(target_viewport.CameraTarget, + target_viewport.CameraX, + target_viewport.CameraY) + + xform = Rhino.Geometry.Transform.PlaneToPlane(source_viewport_plane, target_viewport_plane) + + rs.Command("CPlane View _Enter") + rs.Command("-Make2D Layout=CPlane Properties=MaintainSourceLayers CreateHiddenLines=No ShowTangents=No CreateSceneSilhouette=No CreateClippingPlaneIntersections=No ShowViewRectangle=No GroupOutput=No LayerName " + source_view.Name + " _Enter") + rs.Command("_Enter") + make2d_results = rs.SelectedObjects() + rs.TransformObjects(make2d_results, xform, copy=False) + + sc.doc.Objects.UnselectAll() + source_view.IsActive = False + +BatchMake2D() \ No newline at end of file diff --git a/BlockTools 1.4.rhi b/BlockTools 1.4.rhi new file mode 100644 index 0000000000000000000000000000000000000000..06172ea199ce9eaab904d4ffbd8aed560999dada GIT binary patch literal 17837 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 Q0096z00016MF0Q*0F~MMX8-^I literal 0 HcmV?d00001 diff --git a/BlockUpdate.py b/BlockUpdate.py new file mode 100644 index 0000000..3a6129d --- /dev/null +++ b/BlockUpdate.py @@ -0,0 +1,11 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def BlockUpdate(): + object_ids = rs.GetObjects(preselect=True) + for id in object_ids: + block_instance = sc.doc.Objects.Find(id) + block_definition = block_instance.InstanceDefinition + sc.doc.InstanceDefinitions.RefreshLinkedBlock(block_definition) + +BlockUpdate() \ No newline at end of file diff --git a/BlockUpdateSelected-NOT-WORKING-MISSING-UPDATE-OPTION.py b/BlockUpdateSelected-NOT-WORKING-MISSING-UPDATE-OPTION.py new file mode 100644 index 0000000..ee4d2a2 --- /dev/null +++ b/BlockUpdateSelected-NOT-WORKING-MISSING-UPDATE-OPTION.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs + +def BlockUpdateSelected(): + insts = rs.GetObjects("Select block instnces to refresh.", 4096, preselect=True) + + if insts: + names = [rs.BlockInstanceName(inst)for inst in insts] + pass + for name in list(set(names)): + if not rs.IsBlockEmbedded(name): + rs.Command("-BlockManager Update " + chr(34) +name+ chr(34) + " Enter") +BlockUpdateSelected() diff --git a/ChangeCameraProjection.py b/ChangeCameraProjection.py new file mode 100644 index 0000000..ce59006 --- /dev/null +++ b/ChangeCameraProjection.py @@ -0,0 +1,24 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def ChangeCameraProjection(): + projection_type = ["Parallel", "Perspective", "Two Point"] + projection_selected = rs.ComboListBox(projection_type) + + if projection_selected == None: + return + + if projection_selected == "Parallel": + sc.doc.Views.ActiveView.ActiveViewport.ChangeToParallelProjection(symmetricFrustum=True) + rs.EnableRedraw(True) + rs.Redraw() + if projection_selected == "Perspective": + sc.doc.Views.ActiveView.ActiveViewport.ChangeToPerspectiveProjection(symmetricFrustum=False, lensLength=60) + rs.EnableRedraw(True) + rs.Redraw() + if projection_selected == "Two Point": + sc.doc.Views.ActiveView.ActiveViewport.ChangeToTwoPointPerspectiveProjection(lensLength=60) + rs.EnableRedraw(True) + rs.Redraw() + +ChangeCameraProjection() \ No newline at end of file diff --git a/ChangeLayerInBlockRecursively.py b/ChangeLayerInBlockRecursively.py new file mode 100644 index 0000000..0575028 --- /dev/null +++ b/ChangeLayerInBlockRecursively.py @@ -0,0 +1,34 @@ +import rhinoscriptsyntax as rs + + +def ChangeLayerInBlockRecursively(): + + ids = rs.GetObjects("Select block instances", 4096, preselect=True) + if not ids:return + + targ = rs.GetLayer() + if not targ:return + + names = list(set([rs.BlockInstanceName(id) for id in ids])) + done = [] + + def BlockDrill(names): + while True: + if len (names) > 0 : + name = names.pop() + else: break + + done.append(name) + temp = rs.BlockObjects(name) + rs.ObjectLayer(temp, targ) + + for tempId in temp: + if rs.IsBlockInstance(tempId): + tempName = rs.BlockInstanceName(tempId) + if tempName not in names and tempName not in done: + names.append(tempName) + BlockDrill(names) + + BlockDrill(names) + +if __name__ == "__main__": ChangeLayerInBlockRecursively() \ No newline at end of file diff --git a/ChangeMaterial.py b/ChangeMaterial.py new file mode 100644 index 0000000..3a7b003 --- /dev/null +++ b/ChangeMaterial.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def ChangeMaterial(): + material_names = [i.Name for i in sc.doc.RenderMaterials] + selected_material_name = rs.ComboListBox(sorted(material_names)) + + if selected_material_name == None: + return + + for material in sc.doc.RenderMaterials: + if material.Name == selected_material_name: + selected_material = material + + selected_objects = rs.GetObjects(preselect=True) + + if selected_objects == None: + return + + for selected_object_guid in selected_objects: + selected_object = rs.coercerhinoobject(selected_object_guid) + selected_object.RenderMaterial = selected_material + selected_object.CommitChanges() + +ChangeMaterial() \ No newline at end of file diff --git a/ChangeMaterialForAll.py b/ChangeMaterialForAll.py new file mode 100644 index 0000000..4c8449a --- /dev/null +++ b/ChangeMaterialForAll.py @@ -0,0 +1,40 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +selected_materials = list() + +# get materials of blocks' sub-objects +# looping through all objects due to: https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/12 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + sub_object_ids = object.GetSelectedSubObjects() + if sub_object_ids: + for sub_object_id in sub_object_ids: + sub_object = object.InstanceDefinition.GetObjects()[sub_object_id.Index] + if sub_object.RenderMaterial: + sub_object_material = sub_object.RenderMaterial.Id + selected_materials.append(sub_object_material) + +# get materials of other objects +for object_id in rs.SelectedObjects(): + object = rs.coercerhinoobject(object_id) + if object.RenderMaterial: + object_material = object.RenderMaterial.Id + selected_materials.append(object_material) + +def _SelMaterial(object): + for sub_object_id, sub_object in enumerate(object.InstanceDefinition.GetObjects()): + if type(sub_object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(sub_object) + if sub_object.RenderMaterial and sub_object.RenderMaterial.Id in selected_materials: + object.SelectSubObject(Rhino.Geometry.ComponentIndex(Rhino.Geometry.ComponentIndexType.InstanceDefinitionPart, sub_object_id), True, True, True) + +# select objects by material recursively, even though doesn't work for nested blocks +# https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/13 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(object) + +rs.EnableRedraw() +rs.Redraw() diff --git a/ClipEnableGUI.py b/ClipEnableGUI.py new file mode 100644 index 0000000..9136a2a --- /dev/null +++ b/ClipEnableGUI.py @@ -0,0 +1,30 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def ClipEnable(): + selection_settings = Rhino.DocObjects.ObjectEnumeratorSettings() + selection_settings.ObjectTypeFilter = Rhino.DocObjects.ObjectType.ClipPlane + clip_planes_iterator = sc.doc.Objects.GetObjectList(selection_settings) + + # getobjectlist methods yields an iterator that gets exhausted + # line below converts it into an immutable list + clip_planes = list(clip_planes_iterator) + + clip_plane_names = [clip_plane.Name for clip_plane in clip_planes + if clip_plane.Name is not None] + + selected_clip_planes = rs.MultiListBox(sorted(set(clip_plane_names))) + + if selected_clip_planes == None: + return + + # new gui pop up that selects detail views by name + # which means you'll have to name them + # and addclipview + + selected_clip_planes_guids = [clip_plane.Id for clip_plane in clip_planes + if clip_plane.Name in selected_clip_planes] + + rs.SelectObjects(selected_clip_planes_guids) + +ClipEnable() \ No newline at end of file diff --git a/ClipSelGUI.py b/ClipSelGUI.py new file mode 100644 index 0000000..d4d4f63 --- /dev/null +++ b/ClipSelGUI.py @@ -0,0 +1,29 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def ClipSel(): + selection_settings = Rhino.DocObjects.ObjectEnumeratorSettings() + selection_settings.ObjectTypeFilter = Rhino.DocObjects.ObjectType.ClipPlane + clip_planes_iterator = sc.doc.Objects.GetObjectList(selection_settings) + + # getobjectlist methods yields an iterator that gets exhausted + # line below converts it into an immutable list + clip_planes = list(clip_planes_iterator) + + clip_plane_names = [clip_plane.Name for clip_plane in clip_planes + if clip_plane.Name is not None] + + selected_clip_planes = rs.ComboListBox(sorted(set(clip_plane_names))) + + if selected_clip_planes == None: + return + + # may be a problem if there is only one clipping plane with that name? + + selected_clip_planes_guids = [clip_plane.Id for clip_plane in clip_planes + if clip_plane.Name == selected_clip_planes] + + rs.SelectObjects(selected_clip_planes_guids) + +ClipSel() \ No newline at end of file diff --git a/ClipSelGUIMultiple.py b/ClipSelGUIMultiple.py new file mode 100644 index 0000000..3bb9005 --- /dev/null +++ b/ClipSelGUIMultiple.py @@ -0,0 +1,27 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def ClipSel(): + selection_settings = Rhino.DocObjects.ObjectEnumeratorSettings() + selection_settings.ObjectTypeFilter = Rhino.DocObjects.ObjectType.ClipPlane + clip_planes_iterator = sc.doc.Objects.GetObjectList(selection_settings) + + # getobjectlist methods yields an iterator that gets exhausted + # line below converts it into an immutable list + clip_planes = list(clip_planes_iterator) + + clip_plane_names = [clip_plane.Name for clip_plane in clip_planes + if clip_plane.Name is not None] + + selected_clip_planes = rs.MultiListBox(sorted(set(clip_plane_names))) + + if selected_clip_planes == None: + return + + selected_clip_planes_guids = [clip_plane.Id for clip_plane in clip_planes + if clip_plane.Name in selected_clip_planes] + + rs.SelectObjects(selected_clip_planes_guids) + +ClipSel() \ No newline at end of file diff --git a/ConsolidateLayers.py b/ConsolidateLayers.py new file mode 100644 index 0000000..3c8210f --- /dev/null +++ b/ConsolidateLayers.py @@ -0,0 +1,54 @@ +import scriptcontext as sc +import rhinoscriptsyntax as rs +import collections + +def ConsolidateLayers(): + + layers = rs.LayerNames() + + stripped = [] + top = [] + crnt = False + for layer in layers: + if not rs.LayerChildren(layer) and not crnt: + rs.CurrentLayer(layer) + crnt=True + idx = layer.find("::",1) + if idx>-1: + stripped.append(layer[idx+1:]) + else: + top.append(layer) + pass + dups = [item for item, count in collections.Counter(stripped).items() if count > 1] + + + + + rs.EnableRedraw(False) + for item in dups: + targLayer = None + for tLayer in top: + tempLayer = tLayer+":"+item + if rs.IsLayer(tempLayer): + if not targLayer: + targLayer = tempLayer + ids = rs.ObjectsByLayer(tempLayer) + rs.ObjectLayer(ids, targLayer) + if tempLayer != targLayer: + rs.DeleteLayer(tempLayer) + + if targLayer:pass + + for layer in layers: + if rs.IsLayer(layer): + if rs.IsLayerEmpty(layer): + rs.DeleteLayer(layer) + + # for layer in top: + # if rs.IsLayer(layer): + # print layer + # print rs.PurgeLayer(layer) + + rs.EnableRedraw(True) + +if __name__== '__main__': ConsolidateLayers() \ No newline at end of file diff --git a/ConvertHatchesToSrfs_cmd.py b/ConvertHatchesToSrfs_cmd.py new file mode 100644 index 0000000..01e0c17 --- /dev/null +++ b/ConvertHatchesToSrfs_cmd.py @@ -0,0 +1,23 @@ +import rhinoscriptsyntax as rs + +def RunCommand( is_interactive ): + + #get current color + hatchId = rs.GetObject( + "Pick one hatch", filter=65536, preselect=True, select=True, + subobjects=False) + color = rs.ObjectColor(hatchId) + + #run macro + macro = """ + selcolor invert hide selprev dupborder invert + delete selall planarsrf delete selall join dupborder + invert delete selall planarsrf delete selall group show + """ + rs.Command(macro, echo=False) + + #set previous color as a new material + new_objects = rs.SelectedObjects() + for i in new_objects: + material_idx = rs.AddMaterialToObject(i) + rs.MaterialColor(material_idx, color) \ No newline at end of file diff --git a/ConvertPlanarSrfsToHatch-v8.py b/ConvertPlanarSrfsToHatch-v8.py new file mode 100644 index 0000000..091364c --- /dev/null +++ b/ConvertPlanarSrfsToHatch-v8.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc + +def HatchPlanarSrfs(): + + srfs = rs.GetObjects("select planar surfaces to hatch", filter=8, preselect=True) + if not srfs: + return + for srf in srfs: + srf = rs.coercebrep(srf) + face = srf.Faces[0] + if not face.IsPlanar(): + continue + edges = srf.Edges + edges = [edge.DuplicateCurve() for edge in edges] + edges = Rhino.Geometry.Curve.JoinCurves(edges) + + hatch_solid_idx = sc.doc.HatchPatterns.Find("Solid", True) + hatch = Rhino.Geometry.Hatch.Create(edges, hatch_solid_idx, 0, 0) + sc.doc.Objects.AddHatch(hatch[0]) + sc.doc.Views.Redraw() + +if __name__ == "__main__": + HatchPlanarSrfs() \ No newline at end of file diff --git a/ConvertPlanarSrfsToHatch.py b/ConvertPlanarSrfsToHatch.py new file mode 100644 index 0000000..d53236f --- /dev/null +++ b/ConvertPlanarSrfsToHatch.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc + +def HatchPlanarSrfs(): + + srfs = rs.GetObjects("select planar surfaces to hatch", filter=8, preselect=True) + if not srfs: + return + for srf in srfs: + srf = rs.coercebrep(srf) + face = srf.Faces[0] + if not face.IsPlanar(): + continue + edges = srf.Edges + edges = [edge.DuplicateCurve() for edge in edges] + edges = Rhino.Geometry.Curve.JoinCurves(edges) + + hatch_solid_idx = sc.doc.HatchPatterns.Find("SOLID", True) + hatch = Rhino.Geometry.Hatch.Create(edges, hatch_solid_idx, 0, 0) + sc.doc.Objects.AddHatch(hatch[0]) + sc.doc.Views.Redraw() + +if __name__ == "__main__": + HatchPlanarSrfs() \ No newline at end of file diff --git a/ConvertProjectV8ToV7.py b/ConvertProjectV8ToV7.py new file mode 100644 index 0000000..3b4d4ab --- /dev/null +++ b/ConvertProjectV8ToV7.py @@ -0,0 +1,34 @@ +import os +import rhinoscriptsyntax as rs +import scriptcontext as sc +import System +import subprocess +import Rhino + +block_defs = list(sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True)) + +for idx, block_def in enumerate(block_defs): + if rs.IsBlockEmbedded(block_def.Name) == False and ".3dm" in block_def.SourceArchive: + with open(os.environ['TEMP'] + "\\converting-madness-" + str(idx) + ".cmd", "w") as madness: + + xref_folder, xref_file_name = os.path.split(block_def.SourceArchive) + if not os.path.exists(xref_folder + "\\RhinoV7"): + os.mkdir(xref_folder + "\\RhinoV7") + + madness.write('start /min "" "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\_XrefFilePathSourceV7.py) -saveas version=7 ' + '""' + xref_folder + "\\RhinoV7\\" + xref_file_name + '""' + ' -Exit No" ' + chr(34) + block_def.SourceArchive + chr(34)) + madness.flush() + subprocess.Popen(madness.name, shell=True) + +for idx, block_def in enumerate(block_defs): + if rs.IsBlockEmbedded(block_def.Name) == False and ".3dm" in block_def.SourceArchive: + block_folder, block_file_name = os.path.split(block_def.SourceArchive) + new_block_path = block_folder + "\\RhinoV7\\" + block_file_name + sc.doc.InstanceDefinitions.ModifySourceArchive(block_def.Index, + new_block_path, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 0) + +document_name, document_ext = os.path.splitext(rs.DocumentName()) +rs.Command("-saveas version=7 " + chr(34) + rs.DocumentPath() + document_name + "-V7" + document_ext + chr(34)) +subprocess.Popen(rs.DocumentPath() + document_name + "-V7" + document_ext) +rs.Command("-Exit No") \ No newline at end of file diff --git a/ConvertV8ToV7ForFiles.py b/ConvertV8ToV7ForFiles.py new file mode 100644 index 0000000..7bef28a --- /dev/null +++ b/ConvertV8ToV7ForFiles.py @@ -0,0 +1,21 @@ +import os +import rhinoscriptsyntax as rs +import System +import subprocess + + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Multiselect = True +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + selected_files = dlg.FileNames + +for i, selected_file in enumerate(selected_files): + with open(os.environ['TEMP'] + "\\converting-madness-" + str(i) + ".cmd", "w") as madness: + + selected_file_path, selected_file_name = os.path.split(selected_file) + if not os.path.exists(selected_file_path + "\\v7"): + os.mkdir(selected_file_path + "\\v7") + + madness.write('start /min "" "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-saveas version=7 ' + '""' + selected_file_path + "\\v7\\" + selected_file_name + '""' + ' exit" ' + chr(34) + selected_file + chr(34)) + madness.flush() + subprocess.Popen(madness.name, shell=True) \ No newline at end of file diff --git a/DeleteBlock.py b/DeleteBlock.py new file mode 100644 index 0000000..bc969fa --- /dev/null +++ b/DeleteBlock.py @@ -0,0 +1,8 @@ +import rhinoscriptsyntax as rs + +def DeleteBlock(): + block_names_all = rs.BlockNames() + block_name = rs.ComboListBox(sorted(block_names_all)) + rs.DeleteBlock(block_name) + +DeleteBlock() \ No newline at end of file diff --git a/DeleteNamedCplane.py b/DeleteNamedCplane.py new file mode 100644 index 0000000..dcdd063 --- /dev/null +++ b/DeleteNamedCplane.py @@ -0,0 +1,7 @@ +# need to find a way to escape the last command + +import rhinoscriptsyntax as rs + +named_cplanes = rs.NamedCPlanes() +new_name = rs.ComboListBox(sorted(named_cplanes)) +rs.Command("-NamedCplane Delete " + chr(34) + new_name + chr(34) + " Enter") \ No newline at end of file diff --git a/DisableAllClippingPlanes.py b/DisableAllClippingPlanes.py new file mode 100644 index 0000000..383b4be --- /dev/null +++ b/DisableAllClippingPlanes.py @@ -0,0 +1,11 @@ +import scriptcontext as sc +import Rhino + +def DisableAllClippingPlanes(): + + clipping_planes = [i for i in sc.doc.Objects if type(i) == Rhino.DocObjects.ClippingPlaneObject] + + for clipping_plane in clipping_planes: + clipping_plane.RemoveClipViewport(sc.doc.Views.ActiveView.ActiveViewport, True) + +DisableAllClippingPlanes() \ No newline at end of file diff --git a/EtoForm_MultipleListBox_PrintAllBlockDefinitionsInDocument.py b/EtoForm_MultipleListBox_PrintAllBlockDefinitionsInDocument.py new file mode 100644 index 0000000..63dc07d --- /dev/null +++ b/EtoForm_MultipleListBox_PrintAllBlockDefinitionsInDocument.py @@ -0,0 +1,204 @@ +""" + Show a dialog window with all document layers + Allow searching through the list + + print selected layer name(s) + + +""" +import System + +import Rhino +import Rhino.UI +import rhinoscriptsyntax as rs + +import Eto +import Eto.Drawing as drawing +import Eto.Forms as forms + +import scriptcontext as sc + +import os +import fnmatch + +import itertools +flatten = itertools.chain.from_iterable +graft = itertools.combinations + +# make modal dialog +class DocLayerSelectionDialog(Eto.Forms.Dialog[bool]): + # Initializer + def __init__(self): + # Eto initials + self.Title = "All Layers" + self.Padding = Eto.Drawing.Padding(5) + self.Spacing = Eto.Drawing.Size(5, 5) + + + # fields + self.ScriptList = self.InitializeScriptList() + self.SearchedScriptList = self.ScriptList[::] + + + # initialize layout + layout = Eto.Forms.DynamicLayout() + layout.Padding = Eto.Drawing.Padding(5) + layout.Spacing = Eto.Drawing.Size(5, 5) + + + # add search + layout.BeginVertical() + layout.AddRow(*self.CreateSearchBar()) + layout.EndVertical() + + # add listBox + layout.BeginVertical() + layout.AddRow(self.CreateScriptListBox()) + layout.EndVertical() + + # add buttons + layout.BeginVertical() + layout.AddRow(*self.CreateButtons()) + layout.EndVertical() + + # set content + self.Content = layout + + + + # collect data for list + def InitializeScriptList(self): + return allDocLayers + #return sorted(allDocLayers) + + + # create search bar function + def CreateSearchBar(self): + """ + Creates two controls for the search bar + self.lbl_Search as a simple label + self.tB_Search as a textBox to input search strings to + """ + self.lbl_Search = Eto.Forms.Label() + self.lbl_Search.Text = "Search: " + self.lbl_Search.VerticalAlignment = Eto.Forms.VerticalAlignment.Center + + self.tB_Search = Eto.Forms.TextBox() + self.tB_Search.TextChanged += self.tB_Search_TextChanged + + return [self.lbl_Search, self.tB_Search] + + + + def CreateScriptListBox(self): + # Create a multi selection box with grid view - this is similar to Rhino MultipleListBox + self.lb = forms.GridView() + self.lb.ShowHeader = False + self.lb.AllowMultipleSelection = True + self.lb.Height = 200 + self.lb.AllowColumnReordering = True + + self.lb.DataStore = sorted(allDocLayers) + + self.lb.SelectedRowsChanged += self.RowsChanged + + + # Create Gridview Column + column1 = forms.GridColumn() + column1.Editable = False + column1.Width = 350 + column1.DataCell = forms.TextBoxCell(0) + self.lb.Columns.Add(column1) + + self.lb.DataStore = self.SearchedScriptList + + return self.lb + + + + def CreateButtons(self): + """ + Creates buttons for either print the selection result + or exiting the dialog + """ + self.btn_Run = Eto.Forms.Button() + self.btn_Run.Text = "Run" + self.btn_Run.Click += self.btn_Run_Clicked + + self.btn_Cancel = Eto.Forms.Button() + self.btn_Cancel.Text = "Cancel" + self.btn_Cancel.Click += self.btn_Cancel_Clicked + + return [self.btn_Run, None, self.btn_Cancel] + + + + # create a search function + def Search(self, text): + """ + Searches self.ScriptList with a given string + Supports wildCards + """ + if text == "": + self.lb.DataStore = self.ScriptList + else: + self.SearchedScriptList = list(graft(fnmatch.filter(flatten(self.ScriptList), "*" + text + "*"), 1)) + self.lb.DataStore = self.SearchedScriptList + + + # Gridview SelectedRows Changed Event + def RowsChanged (self,sender,e): + return self.lb.SelectedRows + + + + # function to run when call at button click + def RunScript(self): + # return selected layer names + return self.lb.SelectedValue + + + + # event handler handling text input in ther search bar + def tB_Search_TextChanged(self, sender, e): + self.Search(self.tB_Search.Text) + + + + # event handler handling clicking on the 'run' button + def btn_Run_Clicked(self, sender, e): + # close window after double click action. Otherwise, run with error + self.Close(True) + self.RunScript() + + + # event handler handling clicking on the 'cancel' button + def btn_Cancel_Clicked(self, sender, e): + self.Close(False) + + + +def ShowDocLayerSelectionDialog(): + + dlg = DocLayerSelectionDialog() + rc = Rhino.UI.EtoExtensions.ShowSemiModal(dlg, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow) + + if (rc): + pickedLayers = [] + pickedLayers.append(dlg.RunScript()) + + print pickedLayers + + else: + print "Dialog did not run" + + +if __name__ == "__main__": + docBlocks = rs.BlockNames() + + allDocLayers = [] + i = 0 + while i < len(docBlocks): + allDocLayers.append(docBlocks[i:i+1]) + i += 1 + ShowDocLayerSelectionDialog() \ No newline at end of file diff --git a/EtoForm_MultipleListBox_PrintSelectedLayerName.py b/EtoForm_MultipleListBox_PrintSelectedLayerName.py new file mode 100644 index 0000000..a41c546 --- /dev/null +++ b/EtoForm_MultipleListBox_PrintSelectedLayerName.py @@ -0,0 +1,204 @@ +""" + Show a dialog window with all document layers + Allow searching through the list + + print selected layer name(s) + + +""" +import System + +import Rhino +import Rhino.UI +import rhinoscriptsyntax as rs + +import Eto +import Eto.Drawing as drawing +import Eto.Forms as forms + +import scriptcontext as sc + +import os +import fnmatch + +import itertools +flatten = itertools.chain.from_iterable +graft = itertools.combinations + +# make modal dialog +class DocLayerSelectionDialog(Eto.Forms.Dialog[bool]): + # Initializer + def __init__(self): + # Eto initials + self.Title = "All Layers" + self.Padding = Eto.Drawing.Padding(5) + self.Spacing = Eto.Drawing.Size(5, 5) + + + # fields + self.ScriptList = self.InitializeScriptList() + self.SearchedScriptList = self.ScriptList[::] + + + # initialize layout + layout = Eto.Forms.DynamicLayout() + layout.Padding = Eto.Drawing.Padding(5) + layout.Spacing = Eto.Drawing.Size(5, 5) + + + # add search + layout.BeginVertical() + layout.AddRow(*self.CreateSearchBar()) + layout.EndVertical() + + # add listBox + layout.BeginVertical() + layout.AddRow(self.CreateScriptListBox()) + layout.EndVertical() + + # add buttons + layout.BeginVertical() + layout.AddRow(*self.CreateButtons()) + layout.EndVertical() + + # set content + self.Content = layout + + + + # collect data for list + def InitializeScriptList(self): + return allDocLayers + #return sorted(allDocLayers) + + + # create search bar function + def CreateSearchBar(self): + """ + Creates two controls for the search bar + self.lbl_Search as a simple label + self.tB_Search as a textBox to input search strings to + """ + self.lbl_Search = Eto.Forms.Label() + self.lbl_Search.Text = "Search: " + self.lbl_Search.VerticalAlignment = Eto.Forms.VerticalAlignment.Center + + self.tB_Search = Eto.Forms.TextBox() + self.tB_Search.TextChanged += self.tB_Search_TextChanged + + return [self.lbl_Search, self.tB_Search] + + + + def CreateScriptListBox(self): + # Create a multi selection box with grid view - this is similar to Rhino MultipleListBox + self.lb = forms.GridView() + self.lb.ShowHeader = False + self.lb.AllowMultipleSelection = True + self.lb.Height = 200 + self.lb.AllowColumnReordering = True + + self.lb.DataStore = sorted(allDocLayers) + + self.lb.SelectedRowsChanged += self.RowsChanged + + + # Create Gridview Column + column1 = forms.GridColumn() + column1.Editable = False + column1.Width = 350 + column1.DataCell = forms.TextBoxCell(0) + self.lb.Columns.Add(column1) + + self.lb.DataStore = self.SearchedScriptList + + return self.lb + + + + def CreateButtons(self): + """ + Creates buttons for either print the selection result + or exiting the dialog + """ + self.btn_Run = Eto.Forms.Button() + self.btn_Run.Text = "Run" + self.btn_Run.Click += self.btn_Run_Clicked + + self.btn_Cancel = Eto.Forms.Button() + self.btn_Cancel.Text = "Cancel" + self.btn_Cancel.Click += self.btn_Cancel_Clicked + + return [self.btn_Run, None, self.btn_Cancel] + + + + # create a search function + def Search(self, text): + """ + Searches self.ScriptList with a given string + Supports wildCards + """ + if text == "": + self.lb.DataStore = self.ScriptList + else: + self.SearchedScriptList = list(graft(fnmatch.filter(flatten(self.ScriptList), "*" + text + "*"), 1)) + self.lb.DataStore = self.SearchedScriptList + + + # Gridview SelectedRows Changed Event + def RowsChanged (self,sender,e): + return self.lb.SelectedRows + + + + # function to run when call at button click + def RunScript(self): + # return selected layer names + return self.lb.SelectedValue + + + + # event handler handling text input in ther search bar + def tB_Search_TextChanged(self, sender, e): + self.Search(self.tB_Search.Text) + + + + # event handler handling clicking on the 'run' button + def btn_Run_Clicked(self, sender, e): + # close window after double click action. Otherwise, run with error + self.Close(True) + self.RunScript() + + + # event handler handling clicking on the 'cancel' button + def btn_Cancel_Clicked(self, sender, e): + self.Close(False) + + + +def ShowDocLayerSelectionDialog(): + + dlg = DocLayerSelectionDialog() + rc = Rhino.UI.EtoExtensions.ShowSemiModal(dlg, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow) + + if (rc): + pickedLayers = [] + pickedLayers.append(dlg.RunScript()) + + print pickedLayers + + else: + print "Dialog did not run" + + +if __name__ == "__main__": + docLayers = rs.LayerNames() + + allDocLayers = [] + i = 0 + while i < len(docLayers): + allDocLayers.append(docLayers[i:i+1]) + i += 1 + ShowDocLayerSelectionDialog() \ No newline at end of file diff --git a/ExportDwgSchemeRGBColors.py b/ExportDwgSchemeRGBColors.py new file mode 100644 index 0000000..9de27e8 --- /dev/null +++ b/ExportDwgSchemeRGBColors.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs +import os + +file_name = rs.OpenFileName() +# in case user added extension +file_name_without_ext, file_name_with_ext = os.path.splitext(file_name) +file_name = file_name_without_ext + ".dwg" + +rs.Command('-Export "C:\\Users\\user\\Desktop\\test" Scheme "Default-Copy" _Enter') diff --git a/ExportObjectsToSeparateFiles.py b/ExportObjectsToSeparateFiles.py new file mode 100644 index 0000000..17288ed --- /dev/null +++ b/ExportObjectsToSeparateFiles.py @@ -0,0 +1,36 @@ +"""Export folder is same as current folder if file has been saved; +otherwise, choice of location. +Change format on line 18. +Script by Mitch Heynick 08.07.19""" + +import rhinoscriptsyntax as rs +import scriptcontext as sc +import os + +def ExportObjectsToSeparateFiles(): + names = rs.GetObjects(preselect=True) + + #get folder to save file in + folder=rs.WorkingFolder() + doc_path=rs.DocumentPath() + ft="3dm" + msg="Main file name/folder for {} export?".format(ft) + if doc_path: + msg+=" (Enter to save in current folder)".format(ft) + folder=doc_path + save_folder = rs.BrowseForFolder(folder,msg) + if not save_folder: return + + #start the export sequence + rs.EnableRedraw(False) + for name in names: + e_file_name = '{}.{}'.format(name,ft.lower()) + filename=os.path.join(save_folder,str(e_file_name)) + rs.UnselectAllObjects() + rs.SelectObject(name, redraw=False) + #runs the export using the file name/path and your settings + rs.Command('-_Export "{}" _Enter'.format(filename), echo=True) + rs.UnselectAllObjects() + rs.EnableRedraw(True) + +ExportObjectsToSeparateFiles() diff --git a/ExportViewportsToImages.py b/ExportViewportsToImages.py new file mode 100644 index 0000000..767e85f --- /dev/null +++ b/ExportViewportsToImages.py @@ -0,0 +1,41 @@ +import rhinoscriptsyntax as rs +import Rhino +import os +import scriptcontext as sc +import System.Drawing.Size + +def ExportViewportsToImages(): + + details = Rhino.Display.RhinoPageView.GetDetailViews(sc.doc.Views.ActiveView) + names = [detail.Attributes.Name for detail in details if detail.Attributes.Name != None] + + if len(names) == 0: + rs.MessageBox("No named Viewports found on this page.\n\n" + + "Please give viewports a name that will be used to name output images.\n\n" + + "To do this select each viewport on the sheet and in the properties panel fill in the 'Name' field.", title="Error") + return + + folder = rs.BrowseForFolder() + + for detail in details: + if detail.Attributes.Name: + bbox = rs.BoundingBox(detail.Id) + width = abs(bbox[0].X - bbox[1].X) + length = abs(bbox[1].Y - bbox[2].Y) + size = System.Drawing.Size(width*12, length*12) + + viewcap = Rhino.Display.ViewCapture() + viewcap.TransparentBackground = False + + settings = Rhino.Display.ViewCaptureSettings(sc.doc.Views.ActiveView, size, 300) + settings.SetWindowRect(bbox[0], bbox[2]) + settings.RasterMode = True + settings.DrawGrid = False + settings.DrawAxis = False + settings.DrawWallpaper = False + settings.OutputColor = Rhino.Display.ViewCaptureSettings.ColorMode.DisplayColor + + capture = Rhino.Display.ViewCapture.CaptureToBitmap(settings) + capture.Save(folder + os.path.sep + detail.Attributes.Name + ".jpg") + +ExportViewportsToImages() \ No newline at end of file diff --git a/ExtendCameraTarget.py b/ExtendCameraTarget.py new file mode 100644 index 0000000..af9bff9 --- /dev/null +++ b/ExtendCameraTarget.py @@ -0,0 +1,26 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def PushTarget(): + + vp = sc.doc.Views.ActiveView.ActiveViewport + t = vp.CameraTarget + c = vp.CameraLocation + + factor = 1.25 + if sc.sticky.has_key('TARGET_FACTOR'): + factor = sc.sticky['TARGET_FACTOR'] + + factor = rs.GetReal('Factor', factor, minimum= .1, maximum = None) + if not factor: return + + sc.sticky['TARGET_FACTOR']= factor + + vecDir = t-c + vecDir = vecDir * factor + + vp.SetCameraTarget (c+ vecDir, False) + + sc.doc.Views.Redraw() + +if __name__ == '__main__':PushTarget() \ No newline at end of file diff --git a/FormatTextAreaSquareMeters.py b/FormatTextAreaSquareMeters.py new file mode 100644 index 0000000..2979cba --- /dev/null +++ b/FormatTextAreaSquareMeters.py @@ -0,0 +1,10 @@ +import rhinoscriptsyntax as rs + +obj_guid = rs.GetObject("Select Object to Measure its area", preselect=True) +obj = rs.coercerhinoobject(obj_guid) + +text_guid = rs.GetObject("Select Text Object to report the area", preselect=True) + +format_string = '%% sq m' + +rs.TextObjectText(text_guid, format_string) \ No newline at end of file diff --git a/FormatTextAreaSquareMetersWholeNumbers.py b/FormatTextAreaSquareMetersWholeNumbers.py new file mode 100644 index 0000000..9550eee --- /dev/null +++ b/FormatTextAreaSquareMetersWholeNumbers.py @@ -0,0 +1,10 @@ +import rhinoscriptsyntax as rs + +obj_guid = rs.GetObject("Select Object to Measure its area", preselect=True) +obj = rs.coercerhinoobject(obj_guid) + +text_guid = rs.GetObject("Select Text Object to report the area", preselect=True) + +format_string = '%%' + +rs.TextObjectText(text_guid, format_string) \ No newline at end of file diff --git a/GetActiveViewportParameters.py b/GetActiveViewportParameters.py new file mode 100644 index 0000000..335d4d2 --- /dev/null +++ b/GetActiveViewportParameters.py @@ -0,0 +1,19 @@ +import scriptcontext as sc +from Rhino.UI.Dialogs import ShowTextDialog + +active_viewport = sc.doc.Views.ActiveView.ActiveViewport + +string = str(active_viewport.CameraLocation[0]) + ";" + \ + str(active_viewport.CameraLocation[1]) + ";" + \ + str(active_viewport.CameraLocation[2]) + ";" + \ + str(active_viewport.CameraTarget[0]) + ";" + \ + str(active_viewport.CameraTarget[1]) + ";" + \ + str(active_viewport.CameraTarget[2]) + ";" + \ + str(active_viewport.CameraUp[0]) + ";" + \ + str(active_viewport.CameraUp[1]) + ";" + \ + str(active_viewport.CameraUp[2]) + ";" + \ + "0.0" + ";" + \ + "true" + ";" + \ + str(active_viewport.Camera35mmLensLength) + ";" + +ShowTextDialog(string, "Active Viewport Parameters") \ No newline at end of file diff --git a/GetAllBlockDefinitionsInDocument.py b/GetAllBlockDefinitionsInDocument.py new file mode 100644 index 0000000..95eb03b --- /dev/null +++ b/GetAllBlockDefinitionsInDocument.py @@ -0,0 +1,8 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def GetAllBlockDefinitionsInDocument(): + all_block_definitions = rs.BlockNames() + rs.ComboListBox(all_block_definitions) + +GetAllBlockDefinitionsInDocument() \ No newline at end of file diff --git a/GetAllObjectsNames.py b/GetAllObjectsNames.py new file mode 100644 index 0000000..dde20d0 --- /dev/null +++ b/GetAllObjectsNames.py @@ -0,0 +1,10 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def GetNames(): + object_names = [object.Name for object in sc.doc.Objects if object.Name] + format = "\n".join(sorted(set(object_names))) + Rhino.UI.Dialogs.ShowTextDialog(format, "Block Names") + +GetNames() \ No newline at end of file diff --git a/GetBlocksName.py b/GetBlocksName.py new file mode 100644 index 0000000..a070818 --- /dev/null +++ b/GetBlocksName.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +block_ids = rs.GetObjects(filter=4096, preselect=True) + +if block_ids: + block_names = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_names.append(block_name) + Rhino.UI.Dialogs.ShowTextDialog("\n".join(sorted(block_names)), "Block Names") \ No newline at end of file diff --git a/GetBlocksNameSet.py b/GetBlocksNameSet.py new file mode 100644 index 0000000..6be1ead --- /dev/null +++ b/GetBlocksNameSet.py @@ -0,0 +1,11 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +block_ids = rs.GetObjects(filter=4096, preselect=True) + +if block_ids: + block_names = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_names.append(block_name) + rs.ComboListBox(sorted(list(set(block_names)))) \ No newline at end of file diff --git a/GetBlocksOnLayers.py b/GetBlocksOnLayers.py new file mode 100644 index 0000000..ca8aae2 --- /dev/null +++ b/GetBlocksOnLayers.py @@ -0,0 +1,28 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def GetBlocksOnLayers(): + layer_names = rs.GetLayers() + blocks_using_layer = set() + for layer_name in layer_names: + layer_idx = sc.doc.Layers.FindByFullPath(layer_name, notFoundReturnValue=False) + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + for block_definition in block_definitions: + block_objects = block_definition.GetObjects() + for block_object in block_objects: + if block_object.Attributes.LayerIndex==layer_idx: + blocks_using_layer.add(block_definition.Name) + selected_blocks = rs.MultiListBox(list(blocks_using_layer)) + return selected_blocks + +def InsertSelectedBlocks(selected_blocks): + for selected_block in selected_blocks: + rs.InsertBlock(selected_block, "0,0,0") + +#def InsertSelectedBlocksManually(selected_blocks): +# for selected_block in selected_blocks: +# rs.Command("-Insert _Enter " + chr(34) + selected_block + chr(34)) + +selected_blocks = GetBlocksOnLayers() +InsertSelectedBlocks(selected_blocks) \ No newline at end of file diff --git a/GetGuid.py b/GetGuid.py new file mode 100644 index 0000000..a01c679 --- /dev/null +++ b/GetGuid.py @@ -0,0 +1,5 @@ +import rhinoscriptsyntax as rs + +obj_guid = rs.GetObject(preselect=True) +obj = rs.coercerhinoobject(obj_guid) +rs.ClipboardText(obj.Id) \ No newline at end of file diff --git a/GetGuidToClipboard.py b/GetGuidToClipboard.py new file mode 100644 index 0000000..a01c679 --- /dev/null +++ b/GetGuidToClipboard.py @@ -0,0 +1,5 @@ +import rhinoscriptsyntax as rs + +obj_guid = rs.GetObject(preselect=True) +obj = rs.coercerhinoobject(obj_guid) +rs.ClipboardText(obj.Id) \ No newline at end of file diff --git a/GetLayers.py b/GetLayers.py new file mode 100644 index 0000000..71a3deb --- /dev/null +++ b/GetLayers.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import Rhino + +def GetLayers(): + object_ids = rs.GetObjects(preselect=True) + + if object_ids: + object_layers = set() + for object_id in object_ids: + object_layer = rs.ObjectLayer(object_id) + object_layers.add(object_layer) + format = "\n".join(sorted(object_layers)) + Rhino.UI.Dialogs.ShowTextDialog(format, "Block Names") +# rs.ComboListBox(sorted(list(object_layers))) + +GetLayers() \ No newline at end of file diff --git a/GetNameBlocks.py b/GetNameBlocks.py new file mode 100644 index 0000000..9717bb1 --- /dev/null +++ b/GetNameBlocks.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def GetNameBlocks(): + block_ids = rs.GetObjects(filter=4096, preselect=True) + + if block_ids: + block_names = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_names.append(block_name) + Rhino.UI.Dialogs.ShowTextDialog("\n".join(sorted(block_names)), "Block Names") +# rs.ComboListBox(block_names) + +GetNameBlocks() \ No newline at end of file diff --git a/GetNameSetBlocks.py b/GetNameSetBlocks.py new file mode 100644 index 0000000..5ab3cf6 --- /dev/null +++ b/GetNameSetBlocks.py @@ -0,0 +1,14 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def GetNameSetBlocks(): + block_ids = rs.GetObjects(filter=4096, preselect=True) + + if block_ids: + block_names = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_names.append(block_name) + rs.ComboListBox(sorted(list(set(block_names)))) + +GetNameSetBlocks() \ No newline at end of file diff --git a/GetNames.py b/GetNames.py new file mode 100644 index 0000000..bcc688e --- /dev/null +++ b/GetNames.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs +import Rhino + +def GetNames(): + selected_object_ids = rs.SelectedObjects() + if selected_object_ids == None: return + + selected_object_names = [rs.coercerhinoobject(id).Name for id in selected_object_ids if rs.coercerhinoobject(id).Name] + format = "\n".join(sorted(set(selected_object_names))) + Rhino.UI.Dialogs.ShowTextDialog(format, "Object Names") + +GetNames() \ No newline at end of file diff --git a/Get_Box_Dims.py b/Get_Box_Dims.py new file mode 100644 index 0000000..a9b3d3e --- /dev/null +++ b/Get_Box_Dims.py @@ -0,0 +1,15 @@ +from __future__ import print_function +import Rhino.Geometry.Box as Box + +x,y,z=[],[],[] + +for i in range(len(breps)): + x1,x2 = Box.X.GetValue(breps[i]) + y1,y2 = Box.Y.GetValue(breps[i]) + z1,z2 = Box.Z.GetValue(breps[i]) + + x.append(round(abs(x1-x2)*2)/2) + y.append(round(abs(y1-y2)*2)/2) + z.append(round(abs(z1-z2)*2)/2) + +[print(i,j,k) for i,j,k in zip(x,y,z)] diff --git a/HatchPlanarSrfs-v8.py b/HatchPlanarSrfs-v8.py new file mode 100644 index 0000000..091364c --- /dev/null +++ b/HatchPlanarSrfs-v8.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc + +def HatchPlanarSrfs(): + + srfs = rs.GetObjects("select planar surfaces to hatch", filter=8, preselect=True) + if not srfs: + return + for srf in srfs: + srf = rs.coercebrep(srf) + face = srf.Faces[0] + if not face.IsPlanar(): + continue + edges = srf.Edges + edges = [edge.DuplicateCurve() for edge in edges] + edges = Rhino.Geometry.Curve.JoinCurves(edges) + + hatch_solid_idx = sc.doc.HatchPatterns.Find("Solid", True) + hatch = Rhino.Geometry.Hatch.Create(edges, hatch_solid_idx, 0, 0) + sc.doc.Objects.AddHatch(hatch[0]) + sc.doc.Views.Redraw() + +if __name__ == "__main__": + HatchPlanarSrfs() \ No newline at end of file diff --git a/HatchPlanarSrfs.py b/HatchPlanarSrfs.py new file mode 100644 index 0000000..d53236f --- /dev/null +++ b/HatchPlanarSrfs.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc + +def HatchPlanarSrfs(): + + srfs = rs.GetObjects("select planar surfaces to hatch", filter=8, preselect=True) + if not srfs: + return + for srf in srfs: + srf = rs.coercebrep(srf) + face = srf.Faces[0] + if not face.IsPlanar(): + continue + edges = srf.Edges + edges = [edge.DuplicateCurve() for edge in edges] + edges = Rhino.Geometry.Curve.JoinCurves(edges) + + hatch_solid_idx = sc.doc.HatchPatterns.Find("SOLID", True) + hatch = Rhino.Geometry.Hatch.Create(edges, hatch_solid_idx, 0, 0) + sc.doc.Objects.AddHatch(hatch[0]) + sc.doc.Views.Redraw() + +if __name__ == "__main__": + HatchPlanarSrfs() \ No newline at end of file diff --git a/HideLayerInLayoutDetails.py b/HideLayerInLayoutDetails.py new file mode 100644 index 0000000..576a22c --- /dev/null +++ b/HideLayerInLayoutDetails.py @@ -0,0 +1,40 @@ +__author__ = "Alasdair Mott" +__version__ = "2018.03.15" +# modified 24.11.22 to replace CheckListBox with MultiListBox + +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def hideLayerInLayouts(page): + details = Rhino.Display.RhinoPageView.GetDetailViews(page) + + for i, detail in enumerate(details): + + #rs.CurrentDetail(pageName, detail) + detailId = detail.Id + + for layerString in layers: + + layer_idx = sc.doc.Layers.FindByFullPath(layerString, True) + layer = sc.doc.Layers.FindIndex(layer_idx) + Rhino.DocObjects.Layer.SetPerViewportVisible(layer, detailId, False) + +pageName = rs.CurrentView() +pageNames = rs.ViewNames(True, 1) +pages = sc.doc.Views.GetPageViews() + +""" User Input """ +layers = rs.GetLayers() + +if pageNames and layers: + pageNamesHide = rs.MultiListBox(pageNames, "Layouts to turn off Layer In", "Hide Layer In Layout") + +""" Iterate Pages """ +rs.EnableRedraw(False) +if layers: + if pageNamesHide: + for page in pages: + hideLayerInLayouts(page) +rs.EnableRedraw(True) +rs.Redraw() diff --git a/HideLayers.py b/HideLayers.py new file mode 100644 index 0000000..36b736a --- /dev/null +++ b/HideLayers.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def HideLayers(): + layers=rs.GetLayers() + for layer in layers: + rs.LayerVisible(layer, visible=False) + +# couldn't figure out a faster way to do this :( +def HideLayers2(): + selected_layer = rs.GetLayer() + layer_object = sc.doc.Layers.Find() + layer_object.IsVisible = False + +HideLayers() \ No newline at end of file diff --git a/HideObjectInLayoutDetails-WORK-IN-PROGRESS.py b/HideObjectInLayoutDetails-WORK-IN-PROGRESS.py new file mode 100644 index 0000000..e36ea8e --- /dev/null +++ b/HideObjectInLayoutDetails-WORK-IN-PROGRESS.py @@ -0,0 +1,41 @@ +__author__ = "Alasdair Mott" +__version__ = "2018.03.15" + +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def hideLayerInLayouts(page): + details = Rhino.Display.RhinoPageView.GetDetailViews(page) + + for i, detail in enumerate(details): + + #rs.CurrentDetail(pageName, detail) + detailId = detail.Id + + for layerString in layers: + + layer_idx = sc.doc.Layers.FindByFullPath(layerString, True) + layer = sc.doc.Layers.FindIndex(layer_idx) + Rhino.DocObjects.Layer.SetPerViewportVisible(layer, detailId, False) + +pageName = rs.CurrentView() +pageNames = rs.ViewNames(True, 1) +pages = sc.doc.Views.GetPageViews() + +""" User Input """ +layers = rs.GetLayers() + +if pageNames and layers: + items = [(layout, True) for layout in pageNames] + pageNamesHide = rs.CheckListBox(items, "Layouts to turn off Layer In", "Hide Layer In Layout") + +""" Iterate Pages """ +rs.EnableRedraw(False) +if layers: + if pageNamesHide: + for i, page in enumerate(pages): + if pageNamesHide[i][1] == True: + hideLayerInLayouts(page) +rs.EnableRedraw(True) +rs.Redraw() diff --git a/ImportLayers-WIP.py b/ImportLayers-WIP.py new file mode 100644 index 0000000..74d315f --- /dev/null +++ b/ImportLayers-WIP.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs +import Rhino +import scriptcontext as sc + +rhino_file = rs.OpenFileName() +rhino_file_layers = Rhino.FileIO.File3dm.Read(rhino_file).Layers +selected_layers = rs.ComboListBox(sorted(list(rhino_file_layers))) +a + +for rhino_file_layer in rhino_file_layers: + print(rhino_file_layer) +# sc.doc.Layers.Add() \ No newline at end of file diff --git a/JJ-LayMCur-Make-Object-Layer-Current.py b/JJ-LayMCur-Make-Object-Layer-Current.py new file mode 100644 index 0000000..5cc8a79 --- /dev/null +++ b/JJ-LayMCur-Make-Object-Layer-Current.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs + +object_guids = rs.GetObjects(preselect=True) +if len(object_guids) > 1: + object_layers = list(set([rs.ObjectLayer(i) for i in object_guids])) + selected_layer = rs.ComboListBox(object_layers) + rs.CurrentLayer(selected_layer) +else: + rs.CurrentLayer(rs.ObjectLayer(object_guids[0])) \ No newline at end of file diff --git a/LayoutAddFromClipboard.py b/LayoutAddFromClipboard.py new file mode 100644 index 0000000..e1acc7e --- /dev/null +++ b/LayoutAddFromClipboard.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs + +message = rs.ClipboardText().split("-_-_-") + +page_name = message[0] +page_width = message[1] +page_height = message[2] + +rs.AddLayout(page_name, [float(page_width), float(page_height)]) \ No newline at end of file diff --git a/LayoutCopyToClipboard-WIP.py b/LayoutCopyToClipboard-WIP.py new file mode 100644 index 0000000..e700981 --- /dev/null +++ b/LayoutCopyToClipboard-WIP.py @@ -0,0 +1,17 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import pickle + +#page_width = sc.doc.Views.ActiveView.PageWidth +#page_height = sc.doc.Views.ActiveView.PageHeight +#page_name = sc.doc.Views.ActiveView.PageName +# +#rs.ClipboardText("-_-_-".join([page_name, str(page_width), str(page_height)])) + +page_obj_ids = list() +for obj in sc.doc.Objects: + if obj.Attributes.ViewportId == sc.doc.Views.ActiveView.ActiveViewportID: + page_obj_ids.append(obj.Id) + +#rs.SelectObjects(page_obj_ids) + diff --git a/LayoutCopyToClipboard.py b/LayoutCopyToClipboard.py new file mode 100644 index 0000000..89902e0 --- /dev/null +++ b/LayoutCopyToClipboard.py @@ -0,0 +1,8 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +page_width = sc.doc.Views.ActiveView.PageWidth +page_height = sc.doc.Views.ActiveView.PageHeight +page_name = sc.doc.Views.ActiveView.PageName + +rs.ClipboardText("-_-_-".join([page_name, str(page_width), str(page_height)])) diff --git a/ListAllChangedBlocks.py b/ListAllChangedBlocks.py new file mode 100644 index 0000000..559d9e2 --- /dev/null +++ b/ListAllChangedBlocks.py @@ -0,0 +1,18 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) +block_definitions_list = list(block_definitions) +linked_blocks=[i for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + +changed_blocks = list() +for linked_block in linked_blocks: + if rs.BlockStatus(linked_block.Name) == 1: + changed_blocks.append((linked_block.Name, linked_block.SourceArchive)) + +# might use better string formatting, but will do for now +Rhino.UI.Dialogs.ShowTextDialog("\n".join(sorted([i for sub in changed_blocks for i in sub])), + "Changed Blocks") \ No newline at end of file diff --git a/Make2D.py b/Make2D.py new file mode 100644 index 0000000..9690bb3 --- /dev/null +++ b/Make2D.py @@ -0,0 +1,40 @@ +import Rhino +import rhinoscriptsyntax as rs +import scriptcontext as sc + +a = [view.GetDetailViews() for view in sc.doc.Views.GetPageViews()] +b = [view.PageName for view in sc.doc.Views.GetPageViews()] +c + +if rs.GetDocumentUserText("Child") is None: +# dwg_folder_path = rs.BrowseForFolder("Choose folder to save DWGs into") + a = [view for view in sc.doc.Views.GetPageViews()] + + selected_views = rs.MultiListBox(sorted()) + files = rs.OpenFileNames("Choose files to save as DWG") + for file in files: + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" ' + \ + '/nosplash /runscript="-SetDocumentUserText Child Child ' + \ + '-SetDocumentUserText Export_DWG_folder_path ' + \ + chr(34) + chr(34) + dwg_folder_path + chr(34) + chr(34) + ' ' + \ + '-RunPythonScript (' + __file__ + ') -Exit No" ' + \ + chr(34) + file + chr(34), shell=True) +else: + dwg_folder_path_child = rs.GetDocumentUserText("Export_DWG_folder_path") + rs.Command("-SaveAs " + chr(34) + dwg_folder_path_child + "\\" + \ + os.path.splitext(rs.DocumentName())[0] + ".dwg" + chr(34)) + rs.Command("-Exit No") + + +rs.Command("-Make2D Layout=CPlane Properties=MaintainSourceLayers " + +"CreateHiddenLines=No ShowTangents=No CreateSceneSilhouette=Yes " + +"CreateClippingPlaneIntersections=Yes ShowViewRectangle=Yes " + +"GroupOutput=No " + +"LayerName test2 " + +"_Enter", + echo=True) + +#for reference - methods in RhinoCommon: +#https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_HiddenLineDrawingParameters.htm +#make2d_options = Rhino.Geometry.HiddenLineDrawingParameters() +#Rhino.Geometry.HiddenLineDrawing.Compute() \ No newline at end of file diff --git a/Make2DBatch-WIP.py b/Make2DBatch-WIP.py new file mode 100644 index 0000000..fd63cf6 --- /dev/null +++ b/Make2DBatch-WIP.py @@ -0,0 +1,3 @@ +import rhinoscriptsyntax as rs + +a = rs.VisibleObjects(select=True) \ No newline at end of file diff --git a/MergeLayerTrees-2-WORK-IN-PROGRESS.py b/MergeLayerTrees-2-WORK-IN-PROGRESS.py new file mode 100644 index 0000000..d59e931 --- /dev/null +++ b/MergeLayerTrees-2-WORK-IN-PROGRESS.py @@ -0,0 +1,11 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +a=rs.GetLayer("Get First Layer to Merge") +b=rs.GetLayer("Get Second Layer to Merge") + +c = rs.LayerNames() + +sc.doc.Objects.FindByLayer + +a \ No newline at end of file diff --git a/MergeLayerTrees-WORK-IN-PROGRESS.py b/MergeLayerTrees-WORK-IN-PROGRESS.py new file mode 100644 index 0000000..d1fdfd4 --- /dev/null +++ b/MergeLayerTrees-WORK-IN-PROGRESS.py @@ -0,0 +1,4 @@ +import rhinoscriptsyntax as rs + +layer_tree_from=rs.GetLayers(title="Select Parent Layer to Merge From") +layer_tree_to=rs.GetLayers(title="Select Parent Layer to Merge To") \ No newline at end of file diff --git a/NamedCplaneGUI.py b/NamedCplaneGUI.py new file mode 100644 index 0000000..f754059 --- /dev/null +++ b/NamedCplaneGUI.py @@ -0,0 +1,10 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +named_cplanes = rs.NamedCPlanes() +if not named_cplanes: + raise Exception("No Named CPlanes") +else: + selected_cplane = rs.ComboListBox(sorted(named_cplanes), "Named CPlanes") + +rs.RestoreNamedCPlane(selected_cplane) \ No newline at end of file diff --git a/NamedLayerFilter.py b/NamedLayerFilter.py new file mode 100644 index 0000000..320d35e --- /dev/null +++ b/NamedLayerFilter.py @@ -0,0 +1,22 @@ +import rhinoscriptsyntax as rs +# add globbing +#import glob + +named_layer_filters_str = rs.GetDocumentUserText("Named-Layer-Filters") + +if named_layer_filters_str is None: + selected_filter = rs.ComboListBox(["None"], message="Create a Named Layer Filter") + rs.SetDocumentUserText("Named-Layer-Filters", selected_filter) +else: + named_layer_filters_list = named_layer_filters_str.split(",") + selected_filter = rs.ComboListBox(named_layer_filters_list) + named_layer_filters_list.append(selected_filter) + named_layer_filters_list_new = list(set(named_layer_filters_list)) + named_layer_filters_list_new_str = ",".join(named_layer_filters_list_new) + rs.SetDocumentUserText("Named-Layer-Filters", named_layer_filters_list_new_str) + +visible = rs.ComboListBox(["Show", "Hide"]) +if visible == "Show": + [rs.LayerVisible(layer, visible=True) for layer in rs.LayerNames() if selected_filter in layer] +if visible == "Hide": + [rs.LayerVisible(layer, visible=False) for layer in rs.LayerNames() if selected_filter in layer] \ No newline at end of file diff --git a/NamedViewGUI.py b/NamedViewGUI.py new file mode 100644 index 0000000..5a729dd --- /dev/null +++ b/NamedViewGUI.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +named_views = rs.NamedViews() +if not named_views: + raise Exception("No Named Views") +else: + selected_view = rs.ComboListBox(sorted(named_views), "Named Views") + rs.RestoreNamedView(selected_view) \ No newline at end of file diff --git a/NewNamedCplane.py b/NewNamedCplane.py new file mode 100644 index 0000000..27ea3b4 --- /dev/null +++ b/NewNamedCplane.py @@ -0,0 +1,9 @@ +# need to find a way to escape the last command + +import rhinoscriptsyntax as rs + +named_cplanes = rs.NamedCPlanes() +if not named_cplanes: + named_cplanes = [" "] +new_name = rs.ComboListBox(sorted(named_cplanes), message="Name for the new Named Cplane") +rs.Command("-NamedCplane Save " + chr(34) + new_name + chr(34) + " Enter") \ No newline at end of file diff --git a/ObjectsGroupsToLayers.rvb b/ObjectsGroupsToLayers.rvb new file mode 100644 index 0000000..8d68006 --- /dev/null +++ b/ObjectsGroupsToLayers.rvb @@ -0,0 +1,120 @@ +Option Explicit +'Script written by willemderks.com +'Script version Tuesday, April 12, 2014 + +Call AllGroupsObjectsToIndividualLayers() +Sub AllGroupsObjectsToIndividualLayers() + + Dim arrObj : arrObj = Rhino.GetObjects("Get Objects to distribute to layers") + If isNull(arrObj) Then Exit Sub + + Dim i + Dim digits :digits = Int(len(Cstr(Ubound(arrObj)))) + 1 + Dim tmp + Dim arrGroups + ReDim arrGroups(Ubound(arrObj)) + For i=0 To Ubound(arrObj) + arrGroups(i) = Rhino.ObjectGroups(arrObj(i)) + If Not isNull(arrGroups(i)) Then + tmp = arrGroups(i)(0) + arrGroups(i) = tmp + Else + arrGroups(i) = Null + End If + Next + + Call ArrayCullNull(arrGroups) + + Dim arrObjGrouped : arrObjGrouped = array() + + Dim g,arrG + If Ubound(arrGroups) > -1 Then + arrGroups = Rhino.CullDuplicateStrings(arrGroups) + + + arrObjGrouped = Rhino.MakeArray(Ubound(arrGroups), array()) + + For g=0 To Ubound(arrGroups) + For i=0 To Ubound(arrObj) + If Not isNull(arrObj(i)) Then + arrG = Rhino.ObjectGroups(arrObj(i)) + If Not isNull(arrG) Then + If arrGroups(g) = arrG(0) Then + arrObjGrouped(g) = Rhino.JoinArrays(arrObjGrouped(g), array(arrObj(i))) + arrObj(i) = Null + End If + End If + End If + Next + Next + End If + + + Call ArrayCullNull(arrObj) + If Ubound(arrObj) > -1 Then + For i=0 To Ubound(arrObj) + tmp = array(arrObj(i)) + arrObj(i) = tmp + Next + End If + + Dim arrToDistribute + arrToDistribute = Rhino.JoinArrays(arrObjGrouped, arrObj) + + + If Rhino.MessageBox("Distributing " & Ubound(arrToDistribute) + 1 & " Objects and/or Groups To New layers." & Chr(13) & "Do you want to proceed?", 4 + 48, "Objects and Groups to Layers") = 6 Then + + Dim N,str + N = 1 + For i=0 To Ubound(arrToDistribute) + + + + + Do + str = "OBJ_" & PadDigits(N, digits) + If Not Rhino.IsLayer(str) Then Exit Do + N = N + 1 + + Loop + + + Call Rhino.AddLayer(str, RGB(Rnd * 255, Rnd * 255, Rnd * 255), True, False) + Call Rhino.ObjectLayer(arrToDistribute(i), str) + + Next + + + + + + + End If + + + + +End Sub + +Function ArrayCullNull(ByRef arr) + 'Purges all array items that are Null + 'Returns a newly dimensioned array + 'when all items are purges the array returned is an emoty array with Ubound = -1 + Dim i, j + If IsArray(arr) Then + i = 0 : j = -1 + For i = 0 To UBound(arr) + If Not isNull(arr(i))Then + j = j + 1 + arr(j) = arr(i) + End If + Next + ReDim Preserve arr(j) + End If +End Function + + +Function PadDigits(val, digits) + 'thanks to Dale Fugier + PadDigits = Right(String(digits, "0") & val, digits) +End Function \ No newline at end of file diff --git a/ObjectsToLayerByName.py b/ObjectsToLayerByName.py new file mode 100644 index 0000000..485f62f --- /dev/null +++ b/ObjectsToLayerByName.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs + + +def ObjectsToLayerByName(): + + ids = rs.NormalObjects() + if not ids: return + + for id in ids: + name = rs.ObjectName(id) + if name is not None: + if not rs.IsLayer(name): + rs.AddLayer(name) + rs.ObjectLayer(id, name) + +if __name__ == '__main__': ObjectsToLayerByName() \ No newline at end of file diff --git a/ObjectsToLayers.rvb b/ObjectsToLayers.rvb new file mode 100644 index 0000000..4e2ea48 --- /dev/null +++ b/ObjectsToLayers.rvb @@ -0,0 +1,53 @@ +Option Explicit +'Script written by willemderks.com +'Script version Tuesday, April 1, 2014 09:47:27 + +Call AllObjectsToIndividualLayers() +Sub AllObjectsToIndividualLayers() + + Dim arrObj : arrObj = Rhino.NormalObjects() + If isNull(arrObj) Then Exit Sub + + Dim digits :digits = Int(len(Cstr(Ubound(arrObj)))) + 1 + + + If Rhino.MessageBox("Distributing " & Ubound(arrObj) + 1 & " Objects To New layers." & Chr(13) & "Do you want to proceed?", 4 + 48, "Objects to Layers") = 6 Then + + Dim i,N,str + N = 1 + For i=0 To Ubound(arrObj) + + + + + Do + str = "OBJ_" & PadDigits(N, digits) + If Not Rhino.IsLayer(str) Then Exit Do + N = N + 1 + + Loop + + + Call Rhino.AddLayer(str, RGB(Rnd * 255, Rnd * 255, Rnd * 255), True, False) + Call Rhino.ObjectLayer(arrObj(i), str) + + Next + + + + + + + End If + + + + +End Sub + + + +Function PadDigits(val, digits) + 'thanks to Dale Fugier + PadDigits = Right(String(digits, "0") & val, digits) +End Function \ No newline at end of file diff --git a/OpenBlockWithDefaultApplication.py b/OpenBlockWithDefaultApplication.py new file mode 100644 index 0000000..8954d34 --- /dev/null +++ b/OpenBlockWithDefaultApplication.py @@ -0,0 +1,13 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import os + +def OpenBlockWithDefaultApplication(): + block_ids = rs.GetObjects(filter=4096, preselect=True) + if block_ids: + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_path = rs.BlockPath(block_name) + os.startfile(block_path) + +OpenBlockWithDefaultApplication() \ No newline at end of file diff --git a/OpenBlockWithRhino8WIP.py b/OpenBlockWithRhino8WIP.py new file mode 100644 index 0000000..b6f49af --- /dev/null +++ b/OpenBlockWithRhino8WIP.py @@ -0,0 +1,14 @@ +import rhinoscriptsyntax as rs +#import os +import subprocess + +def OpenBlockWithRhino8WIP(): + block_ids = rs.GetObjects(filter=4096, preselect=True) + if block_ids: + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_path = rs.BlockPath(block_name) +# os.system("C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" + " " + block_path) + subprocess.Popen(["C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe", block_path], close_fds=True) + +OpenBlockWithRhino8WIP() \ No newline at end of file diff --git a/ParentLayer.py b/ParentLayer.py new file mode 100644 index 0000000..f8bdd95 --- /dev/null +++ b/ParentLayer.py @@ -0,0 +1,7 @@ +import rhinoscriptsyntax as rs + +layers = rs.GetLayers(title="Select Layers to move") +layer_parent = rs.GetLayer(title="Select Parent") + +for layer in layers: + rs.ParentLayer(layer, layer_parent) diff --git a/PrintAllAsSeparatePages.py b/PrintAllAsSeparatePages.py new file mode 100644 index 0000000..c5716dc --- /dev/null +++ b/PrintAllAsSeparatePages.py @@ -0,0 +1,56 @@ +import Rhino +import scriptcontext as sc +import System.Drawing +import rhinoscriptsyntax as rs +import os + +folder = rs.BrowseForFolder() +titleblock = dict() + +def createSinglePDF(view, titleblock): + pdf = Rhino.FileIO.FilePdf.Create() + dpi = 300 + settings = Rhino.Display.ViewCaptureSettings(view, dpi) + settings.OutputColor = Rhino.Display.ViewCaptureSettings.ColorMode.DisplayColor + settings.DefaultPrintWidthMillimeters = 0.18 + pdf.AddPage(settings) + filename = folder + "\\" + titleblock.get("project_number","0000") + "-" + \ + titleblock.get("originator", "00") + "-" + \ + titleblock.get("zone", "00") + "-" + \ + titleblock.get("level", "00") + "-" + \ + titleblock.get("drawing_type", "00") + "-" + \ + titleblock.get("role", "0") + "-" + \ + titleblock.get("drawing_number", "00000") + "_" + \ + titleblock.get("latest_revision", "00") + " " + \ + titleblock.get("drawing_title_1", "000000000") + " " + \ + titleblock.get("drawing_title_2", "") + " " + \ + titleblock.get("drawing_title_3", "") + ".pdf" + pdf.Write(filename) + +for view in sc.doc.Views.GetPageViews(): + for object in sc.doc.Objects.FindByLayer("titleblock index-AR002"): + if type(object) == Rhino.DocObjects.TextObject and \ + view.ActiveViewportID == object.Attributes.ViewportId: + if object.Name == "Project Number": + titleblock["project_number"] = object.DisplayText + if object.Name == "Originator": + titleblock["originator"] = object.DisplayText + if object.Name == "Zone": + titleblock["zone"] = object.DisplayText + if object.Name == "Level": + titleblock["level"] = object.DisplayText + if object.Name == "Drawing Type": + titleblock["drawing_type"] = object.DisplayText + if object.Name == "Role": + titleblock["role"] = object.DisplayText + if object.Name == "Drawing Number": + titleblock["drawing_number"] = object.DisplayText + if object.Name == "Latest Revision": + titleblock["latest_revision"] = object.DisplayText + if object.Name == "Drawing Title 1": + titleblock["drawing_title_1"] = object.DisplayText + if object.Name == "Drawing Title 2": + titleblock["drawing_title_2"] = object.DisplayText + if object.Name == "Drawing Title 3": + titleblock["drawing_title_3"] = object.DisplayText + createSinglePDF(view, titleblock) \ No newline at end of file diff --git a/PrintAllAsSeparatePagesMultiprocess.py b/PrintAllAsSeparatePagesMultiprocess.py new file mode 100644 index 0000000..897867d --- /dev/null +++ b/PrintAllAsSeparatePagesMultiprocess.py @@ -0,0 +1,90 @@ +import Rhino +import scriptcontext as sc +import rhinoscriptsyntax as rs +import os +import subprocess +import System.Drawing + +def createSinglePDF(view, titleblock): + pdf = Rhino.FileIO.FilePdf.Create() + dpi = 300 + settings = Rhino.Display.ViewCaptureSettings(view, dpi) + settings.OutputColor = Rhino.Display.ViewCaptureSettings.ColorMode.DisplayColor + settings.DefaultPrintWidthMillimeters = 0.18 + pdf.AddPage(settings) + filename = folder + os.path.sep + titleblock.get("project_number","0000") + "-" + \ + titleblock.get("originator", "00") + "-" + \ + titleblock.get("zone", "00") + "-" + \ + titleblock.get("level", "00") + "-" + \ + titleblock.get("drawing_type", "00") + "-" + \ + titleblock.get("role", "0") + "-" + \ + titleblock.get("drawing_number", "00000") + "_" + \ + titleblock.get("latest_revision", "00") + " " + \ + titleblock.get("drawing_title_1", "000000000") + " " + \ + titleblock.get("drawing_title_2", "") + " " + \ + titleblock.get("drawing_title_3", "") + ".pdf" + # FIX ME - special formatting variables aka <%%> don't seem to work + # https://discourse.mcneel.com/t/displaytext-property-of-text-objects-returns-text-field-aka/150514 + pdf.Write(filename) + +def print_views(): + print_chunk_pages_str = rs.GetDocumentUserText("Print_Chunk_Pages").split("--||--") + # cast to integer in case 'if in' below didn't work for strings + print_chunk_pages = [int(i) for i in print_chunk_pages_str] + for view in sc.doc.Views.GetPageViews(): + if int(view.PageNumber) in print_chunk_pages: + for object in sc.doc.Objects.FindByLayer("titleblock index-AR002"): + if type(object) == Rhino.DocObjects.TextObject and \ + view.ActiveViewportID == object.Attributes.ViewportId: + if object.Name == "Project Number": + titleblock["project_number"] = object.DisplayText + if object.Name == "Originator": + titleblock["originator"] = object.DisplayText + if object.Name == "Zone": + titleblock["zone"] = object.DisplayText + if object.Name == "Level": + titleblock["level"] = object.DisplayText + if object.Name == "Drawing Type": + titleblock["drawing_type"] = object.DisplayText + if object.Name == "Role": + titleblock["role"] = object.DisplayText + if object.Name == "Drawing Number": + titleblock["drawing_number"] = "{0}".format(object.DisplayText) + if object.Name == "Latest Revision": + titleblock["latest_revision"] = object.DisplayText + if object.Name == "Drawing Title 1": + titleblock["drawing_title_1"] = object.DisplayText + if object.Name == "Drawing Title 2": + titleblock["drawing_title_2"] = object.DisplayText + if object.Name == "Drawing Title 3": + titleblock["drawing_title_3"] = object.DisplayText + createSinglePDF(view, titleblock) + +# get folder +folder = rs.GetDocumentData("Print", "Folder") +if folder is None: + folder = rs.BrowseForFolder(message="choose location for PDFs - " + \ + "once chosen won't prompt for it again, " + \ + "can be changed in Rhino - Options " + \ + "- Document User Text") + rs.SetDocumentData("Print", "Folder", folder) + + # prompt to save the file with the above variable in DocumentUserData + # so subprocesses can use it + answer = rs.ComboListBox(["yes", "no"], message="Need to save the file first, proceed?") + if answer == "yes": + rs.Command("-Save _Enter") + else: + raise Exception('User chose not to save the file - exiting...') + +if rs.GetDocumentUserText("Child") is None: + # number of child processes + n = 3 + for i in xrange(n): + print_chunk_pages = [view.PageNumber for view in sc.doc.Views.GetPageViews()[i::n]] + print_chunk_pages_str = [str(i) for i in print_chunk_pages] + print_chunk_pages_str_joined = "--||--".join(print_chunk_pages_str) + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-SetDocumentUserText Child Child -SetDocumentUserText Print_Chunk_Pages ' + print_chunk_pages_str_joined + ' -RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\PrintAllAsSeparatePagesMultiprocess.py) -Exit No" ' + chr(34) + rs.DocumentPath() + "\\" + rs.DocumentName() + chr(34), shell=True) +else: + titleblock = dict() + print_views() \ No newline at end of file diff --git a/PrintForFiles-WIP.py b/PrintForFiles-WIP.py new file mode 100644 index 0000000..33eed3f --- /dev/null +++ b/PrintForFiles-WIP.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import subprocess +import os + +if rs.GetDocumentUserText("Child") is None: + files = rs.OpenFileNames("choose files to convert curves to lines") + for file in files: + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" ' + \ + '/nosplash /runscript="-SetDocumentUserText Child Child ' + \ + '-RunPythonScript (' + __file__ + ')" ' + \ + chr(34) + file + chr(34), shell=True) +else: + rs.Command("_SelLine") + rs.Command("_Convert Output=Lines SimplifyInput=No DeleteInput=Yes OutputLayer=Input _Enter") + rs.Command("Save") + rs.Command("Exit") \ No newline at end of file diff --git a/ProximityNetworkCurves-GhPlayer.gh b/ProximityNetworkCurves-GhPlayer.gh new file mode 100644 index 0000000000000000000000000000000000000000..df9900fa88081dfea96134dff5f544d9862d3c97 GIT binary patch literal 9186 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 QCO_yhH?cM@H1v%49|OsDm;e9( literal 0 HcmV?d00001 diff --git a/RemapCplaneCopyGUI.py b/RemapCplaneCopyGUI.py new file mode 100644 index 0000000..df05625 --- /dev/null +++ b/RemapCplaneCopyGUI.py @@ -0,0 +1,14 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplanes_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + +current_cplane = rs.ViewCPlane() +rs.RestoreNamedCPlane(selected_cplanes_from) + +rs.Command("RemapCplane Copy=Yes Cplane " + chr(34) + selected_cplane_to + chr(34)) + +#restore previous Cplane +rs.ViewCPlane(plane=current_cplane) \ No newline at end of file diff --git a/RemapCplaneCopyMultipleGUI.py b/RemapCplaneCopyMultipleGUI.py new file mode 100644 index 0000000..dbb309e --- /dev/null +++ b/RemapCplaneCopyMultipleGUI.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs + +named_cplanes = rs.NamedCPlanes() +selected_cplanes_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplanes_to = rs.MultiListBox(sorted(named_cplanes), "Cplane to Map to") + +current_cplane = rs.ViewCPlane() + +rs.RestoreNamedCPlane(selected_cplanes_from) + +for selected_cplane_to in selected_cplanes_to: + rs.Command("RemapCplane Copy=Yes Cplane " + chr(34) + selected_cplane_to + chr(34)) + +#restore previous Cplane +rs.ViewCPlane(plane=current_cplane) \ No newline at end of file diff --git a/RemapCplaneGUI-WIP.py b/RemapCplaneGUI-WIP.py new file mode 100644 index 0000000..5261fc7 --- /dev/null +++ b/RemapCplaneGUI-WIP.py @@ -0,0 +1,9 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplane_to = rs.ComboListBox(named_cplanes, "Cplane to Map to") +selected_cplane_from = rs.ComboListBox(named_cplanes, "Cplane to Map from") + +rs.ViewCPlane(plane=selected_cplane_to) +rs.Command("RemapCplane Cplane " + selected_cplane) \ No newline at end of file diff --git a/RemapCplaneGUI.py b/RemapCplaneGUI.py new file mode 100644 index 0000000..b50329d --- /dev/null +++ b/RemapCplaneGUI.py @@ -0,0 +1,31 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +#doesn't work when this section turned on - try using transforms instead: + +#selected_obj = rs.coercerhinoobject(rs.GetObject(preselect=True)) +#if str(selected_obj.ObjectType) == "InstanceReference": +# selected_obj_name = selected_obj.InstanceDefinition.Name +#else: +# selected_obj_name = "" + +named_cplanes = [i.Name for i in list(sc.doc.NamedConstructionPlanes.GetEnumerator())] +selected_cplane_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + + +#doesn't work when this section turned on - try using transforms instead: +#message_from = "Name: " + selected_obj_name + "\n" + "Cplane to Map from" +#message_to = "Name: " + selected_obj_name + "\n" + "Cplane to Map to" + +#selected_cplane_from = rs.ComboListBox(sorted(named_cplanes), message=message_from) +#selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), message=message_to) + + +current_cplane = rs.ViewCPlane() +rs.RestoreNamedCPlane(selected_cplane_from) + +rs.Command("RemapCplane Copy=Yes Cplane " + chr(34) + selected_cplane_to + chr(34)) + +#restore previous Cplane +rs.ViewCPlane(plane=current_cplane) \ No newline at end of file diff --git a/RemapCplaneMultipleGUI.py b/RemapCplaneMultipleGUI.py new file mode 100644 index 0000000..76f1c64 --- /dev/null +++ b/RemapCplaneMultipleGUI.py @@ -0,0 +1,32 @@ +# something's not workign - check remapcplanecopygui + +import rhinoscriptsyntax as rs + +def RemapCplaneCopyMultipleGUI(): + # if it's a block show it's name in the message title + # should be developed to take other objects' names + selected_obj = rs.coercerhinoobject(rs.GetObject(preselect=True)) + if str(selected_obj.ObjectType) == "InstanceReference": + selected_obj_name = selected_obj.InstanceDefinition.Name + else: + selected_obj_name = "" + + named_cplanes = rs.NamedCPlanes() + + selected_cplane_from = rs.ComboListBox(sorted(named_cplanes), "Name: " + selected_obj_name + "\n" + "Cplane to Map from") + selected_cplane_to = rs.ComboListBox(sorted(named_cplanes), "Name: " + selected_obj_name + "\n" + "Cplane to Map to") + + current_cplane = rs.ViewCPlane() + rs.RestoreNamedCPlane(selected_cplane_from) + + if selected_cplane_from == None or selected_cplane_to == None: + return + + # needs to find a way to take a list from a combolistbox +# for selected_cplane_to in list(selected_cplanes_to): + rs.Command("RemapCplane Copy=Yes Cplane " + chr(34) + selected_cplane_to + chr(34)) + + #restore previous Cplane + rs.ViewCPlane(plane=current_cplane) + +RemapCplaneCopyMultipleGUI() \ No newline at end of file diff --git a/RemapView.py b/RemapView.py new file mode 100644 index 0000000..0b5fd69 --- /dev/null +++ b/RemapView.py @@ -0,0 +1,26 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +vp = sc.doc.Views.ActiveView.ActiveViewport + +named_cplanes = [i.Name for i in sc.doc.NamedConstructionPlanes] +selected_cplane_name_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplane_name_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + +for i in sc.doc.NamedConstructionPlanes: + if i.Name == selected_cplane_name_from: + plane1 = i.Plane + if i.Name == selected_cplane_name_to: + plane2 = i.Plane + +xform = Rhino.Geometry.Transform.PlaneToPlane(plane1, plane2) +info = Rhino.DocObjects.ViewportInfo(vp) + +info.TransformCamera(xform) + +vp.SetCameraLocation(info.CameraLocation, False) +vp.SetCameraTarget(info.TargetPoint, False) +vp.SetCameraDirection (info.CameraDirection, True) +vp.CameraUp = (info.CameraUp) +sc.doc.Views.Redraw() \ No newline at end of file diff --git a/RemapViewGUI.py b/RemapViewGUI.py new file mode 100644 index 0000000..0b5fd69 --- /dev/null +++ b/RemapViewGUI.py @@ -0,0 +1,26 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +vp = sc.doc.Views.ActiveView.ActiveViewport + +named_cplanes = [i.Name for i in sc.doc.NamedConstructionPlanes] +selected_cplane_name_from = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map from") +selected_cplane_name_to = rs.ComboListBox(sorted(named_cplanes), "Cplane to Map to") + +for i in sc.doc.NamedConstructionPlanes: + if i.Name == selected_cplane_name_from: + plane1 = i.Plane + if i.Name == selected_cplane_name_to: + plane2 = i.Plane + +xform = Rhino.Geometry.Transform.PlaneToPlane(plane1, plane2) +info = Rhino.DocObjects.ViewportInfo(vp) + +info.TransformCamera(xform) + +vp.SetCameraLocation(info.CameraLocation, False) +vp.SetCameraTarget(info.TargetPoint, False) +vp.SetCameraDirection (info.CameraDirection, True) +vp.CameraUp = (info.CameraUp) +sc.doc.Views.Redraw() \ No newline at end of file diff --git a/ReopenThisFileWithoutSaving-WIP.py b/ReopenThisFileWithoutSaving-WIP.py new file mode 100644 index 0000000..86767c2 --- /dev/null +++ b/ReopenThisFileWithoutSaving-WIP.py @@ -0,0 +1,5 @@ +# can't get it to work when file isn't saved, below commands return None +import rhinoscriptsyntax as rs + +document_location = rs.DocumentPath() + rs.DocumentName() +rs.Command("Open No " + chr(34) + document_location + chr(34)) \ No newline at end of file diff --git a/ReplaceBlockFromFile.py b/ReplaceBlockFromFile.py new file mode 100644 index 0000000..0bfe05a --- /dev/null +++ b/ReplaceBlockFromFile.py @@ -0,0 +1,19 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def ReplaceBlockFromFile(): + new_block_file_path = rs.OpenFileName() + + sc.doc.ActiveDoc.InstanceDefinitions.ModifySourceArchive( + + block_ids = rs.GetObjects(filter=4096, preselect=True) + + if block_ids: + block_paths = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_path = rs.BlockPath(block_name) + block_paths.append(block_path) + rs.ComboListBox(block_paths) + +ReplaceBlockFromFile() \ No newline at end of file diff --git a/ResetTransformation.py b/ResetTransformation.py new file mode 100644 index 0000000..0952a0c --- /dev/null +++ b/ResetTransformation.py @@ -0,0 +1,20 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +def RunCommand( is_interactive ): + if sc.escape_test(False): + print "script cancelled" #do something + print "Resetting..." + objectIds = rs.GetObjects("Pick some blocks", 4096, preselect=True) + if not objectIds: + print "No objects" + return False + rs.EnableRedraw(False) + for id in objectIds: + blockXForm = rs.BlockInstanceXform(id) + inverseBlockXForm = blockXForm.TryGetInverse()[1] + rs.TransformObject(id, inverseBlockXForm) + rs.SelectObjects(objectIds) + rs.EnableRedraw(True) + print "...aaand its done." + return 0 +RunCommand(True) \ No newline at end of file diff --git a/Rhino-Aliases.txt b/Rhino-Aliases.txt new file mode 100644 index 0000000..50541bf --- /dev/null +++ b/Rhino-Aliases.txt @@ -0,0 +1,162 @@ +Z '_Zoom +ZE '_Zoom _Extents +ZEA '_Zoom _All _Extents +ZS '_Zoom _Selected +ZSA '_Zoom _All _Selected +S '_Snap +O '_Ortho +P '_Planar +M ! _Move +U _Undo +POn ! _PointsOn +POff ! _PointsOff +C '_SelCrossing +W '_SelWindow +COn '_CurvatureGraph +COff '_CurvatureGraphOff +PlugInManager ! _OptionsPage _PlugIns +AdvancedDisplay ! _OptionsPage _DisplayModes +DisplayAttrsMgr ! _OptionsPage _DisplayModes +Break ! _DeleteSubCrv +SelPolysurface '_SelPolysrf +seoltSelEntireObjLayerTree -RunPythonScript "Z:\scripts\rhino\SelEntireObjLayerTree.py" +solSelObjectsLayer -RunPythonScript "Z:\scripts\rhino\SelObjectsLayer-1.py" +ConvertPlanarSrfsToHatch -RunPythonScript "Z:\scripts\rhino\ConvertPlanarSrfsToHatch-v8.py" +ChangeLayerInBlockRecursively -RunPythonScript "Z:\scripts\rhino\ChangeLayerInBlockRecursively.py" +ShowLayerInLayoutDetails -RunPythonScript "Z:\scripts\rhino\ShowLayerInLayoutDetails.py" +HideLayerInLayoutDetails -RunPythonScript "Z:\scripts\rhino\HideLayerInLayoutDetails.py" +nvstNamedViewSaveTemp -NamedView Save temp _Enter +nvrtNamedViewRestoreTemp -NamedView Restore temp _Enter LockViewport +SelLayerTree -RunPythonScript "Z:\scripts\rhino\SelLayerTree.py" +GetLayers -RunPythonScript "Z:\scripts\rhino\GetLayers.py" +xfpXrefFilePaths -RunPythonScript "Z:\scripts\rhino\XrefFilePaths.py" +xfpsXrefFilePathsSet -RunPythonScript "Z:\scripts\rhino\XrefFilePathsSet.py" +buBlockUpdate -RunPythonScript "Z:\scripts\rhino\BlockUpdate.py" _Pause _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter +ExportObjectsToSeparateFiles -RunPythonScript "Z:\scripts\rhino\ExportObjectsToSeparateFiles.py" +OpenBlockWithDefaultApplication -RunPythonScript "Z:\scripts\rhino\OpenBlockWithDefaultApplication.py" +SearchBlockDefinitions -RunPythonScript "Z:\scripts\rhino\EtoForm_MultipleListBox_PrintAllBlockDefinitionsInDocument.py" +SearchLayers -RunPythonScript "Z:\scripts\rhino\EtoForm_MultipleListBox_PrintSelectedLayerName.py" +ResetTransformation -RunPythonScript "Z:\scripts\rhino\ResetTransformation.py" +NewNoTemplate -New None +OpenBlockWithRhino8WIP -RunPythonScript "Z:\scripts\rhino\OpenBlockWithRhino8WIP.py" +GetBlocksOnLayers -RunPythonScript "Z:\scripts\rhino\GetBlocksOnLayers.py" +ParentLayer -RunPythonScript "Z:\scripts\rhino\ParentLayer.py" +solt1SelObjLayerTree1 -RunPythonScript "Z:\scripts\rhino\SelObjLayerTree1.py" +solt2SelObjLayerTree2 -RunPythonScript "Z:\scripts\rhino\SelObjLayerTree2.py" +RebuildSurfaceBorder -GrasshopperPlayer "Z:\scripts\rhino\RebuildSurfaceBorder-GhPlayer.gh" +ProximityNetworkCurves -GrasshopperPlayer "Z:\scripts\rhino\ProximityNetworkCurves-GhPlayer.gh" +svctSetViewCplaneTop -SetView Cplane Top +xsXrefShow -RunPythonScript "Z:\scripts\rhino\XrefShow.py" +xhXrefHide -RunPythonScript "Z:\scripts\rhino\XrefHide.py" +slShowLayers -RunPythonScript "Z:\scripts\rhino\ShowLayers.py" +hlHideLayers -RunPythonScript "Z:\scripts\rhino\HideLayers.py" +XrefHideBlocks -RunPythonScript "Z:\scripts\rhino\XrefHideBlocks.py" +XrefShowBlocks -RunPythonScript "Z:\scripts\rhino\XrefShowBlocks.py" +XrefShowLayersAndBlocks -RunPythonScript "Z:\scripts\rhino\XrefShowLayersAndBlocks.py" +UpdateAllChangedBlocks -RunPythonScript "Z:\scripts\rhino\UpdateAllChangedBlocks.py" _Pause _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter _Enter +XrefSel -RunPythonScript "Z:\scripts\rhino\XrefSel.py" +XrefShowAll -RunPythonScript "Z:\scripts\rhino\XrefShowAll.py" +PrintAllAsSeparatePages -RunPythonScript "Z:\scripts\rhino\PrintAllAsSeparatePages.py" +DeleteBlock -RunPythonScript "Z:\scripts\rhino\DeleteBlock.py" +SelBlockNames -RunPythonScript "Z:\scripts\rhino\SelBlockNames.py" +SetLayerPrintWidthsToMatchCTB -RunPythonScript "Z:\scripts\rhino\SetLayerPrintWidthsToMatchCTB.py" +SetLayerPrintWidthsToMatchCTBForFiles -RunPythonScript "Z:\scripts\rhino\SetLayerPrintWidthsToMatchCTBForFiles.py" +PrintAllAsSeparatePagesMultiprocess -RunPythonScript "Z:\scripts\rhino\PrintAllAsSeparatePagesMultiprocess.py" +ConvertV8ToV7ForFiles -RunPythonScript "Z:\scripts\rhino\ConvertV8ToV7ForFiles.py" +xtXrefToggleVisibility -RunPythonScript "Z:\scripts\rhino\XrefToggleVisibility.py" +ConvertProjectV8ToV7 -RunPythonScript "Z:\scripts\rhino\ConvertProjectV8ToV7.py" +xmpXrefModifyPath -RunPythonScript "Z:\scripts\rhino\XrefModifyPath.py" +SelObjectsLayer -RunPythonScript "Z:\scripts\rhino\SelObjectsLayer-1-mine.py" +ListAllChangedBlocks -RunPythonScript "Z:\scripts\rhino\ListAllChangedBlocks.py" +XrefChangePathWithoutRenaming -RunPythonScript "Z:\scripts\rhino\XrefChangePathWithoutRenaming.py" +GetGuidToClipboard -RunPythonScript "Z:\scripts\rhino\GetGuidToClipboard.py" +FormatTextAreaSquareMeters -RunPythonScript "Z:\scripts\rhino\FormatTextAreaSquareMeters.py" +lctcLayoutCopyToClipboard -RunPythonScript "Z:\scripts\rhino\LayoutCopyToClipboard.py" +lafcLayoutAddFromClipboard -RunPythonScript "Z:\scripts\rhino\LayoutAddFromClipboard.py" +ncgNamedCplaneGUI -RunPythonScript "Z:\scripts\rhino\NamedCplaneGUI.py" +rcgRemapCplaneGUI -RunPythonScript "Z:\scripts\rhino\RemapCplaneGUI.py" +ilIsolateLock IsolateLock +ssShowSelected ShowSelected +qetsQuickExportToDWG -RunPythonScript "Z:\scripts\rhino\QuickExportToDWG-NewScheme.py" +nncNewNamedCplane -RunPythonScript "Z:\scripts\rhino\NewNamedCplane.py" +dncDeleteNamedCplane -RunPythonScript "Z:\scripts\rhino\DeleteNamedCplane.py" +zzsSetViewCplaneZoomSelected -SetView Cplane Top '_Zoom _Selected +xiitspXrefInsertInTheSamePlace -RunPythonScript "Z:\scripts\rhino\XrefInsertInTheSamePlace.py" +xewmbpXrefExportWithModelBasePoint -RunPythonScript "Z:\scripts\rhino\XrefExportWithModelBasePoint.py" +gbnGetBlocksName -RunPythonScript "Z:\scripts\rhino\GetBlocksName.py" +gbnsGetBlocksNameSet -RunPythonScript "Z:\scripts\rhino\GetBlocksNameSet.py" +ndtNewDefaultTemplate -New Default +ndatNewDefaultA1Template -New Default-A1 +xmutXrefModifyUpdateType -RunPythonScript "Z:\scripts\rhino\XrefModifyUpdateType.py" +xcctlffXrefConvertCurvesToLinesForFiles -RunPythonScript "Z:\scripts\rhino\XrefConvertCurvesToLinesForFiles.py" +SaveAsDWGForFiles -RunPythonScript "Z:\scripts\rhino\SaveAsDWGForFiles.py" +rvRemapView -RunPythonScript "Z:\scripts\rhino\RemapView.py" +iiIsolate _Isolate +qsatsQuickSaveAsToDWG -RunPythonScript "Z:\scripts\rhino\QuickSaveAsToDWG.py" +SetLayerColorsToMatchCTBForFiles -RunPythonScript "Z:\scripts\rhino\SetLayerColorsToMatchCTBForFiles.py" +XrefExportSeparateAsDWG -RunPythonScript "Z:\scripts\rhino\XrefExportSeparateAsDWG.py" +jjLayMCur_MakeObjectLayerCurrent -RunPythonScript "Z:\scripts\rhino\jjLayMCur_MakeObjectLayerCurrent.py" +cbCurveBoolean CurveBoolean +FormatTextAreaSquareMetersWholeNumbers -RunPythonScript "Z:\scripts\rhino\FormatTextAreaSquareMetersWholeNumbers.py" +ExportDwgSchemeRGBColors _Export +ExportDwgSchemeIndexColors -Export Browse Scheme "Default-Copy" _Enter +beBlockEdit BlockEdit +ClipSelGUI -RunPythonScript "Z:\scripts\rhino\ClipSelGUI.py" +ccpChangeCameraProjection -RunPythonScript "Z:\scripts\rhino\ChangeCameraProjection.py" +ww what +pococPropertiesObjectColorObjectColorPicker -Properties Object Color Object ColorPicker _Enter _Enter +pdstPrintDisplayStateToggle -PrintDisplay State Toggle _Enter +mmMatchMaterial -MatchProperties _Pause _Pause Name=No Layer=No DisplayColor=No DisplayMode=No Linetype=No LinetypeScale=No PrintColor=No PrintWidth=No Clip=No SectionStyle=No Hyperlink=No CustomMesh=No CastsShadows=No ReceivesShadows=No IsocurveDensity=No Material=Yes CurvePiping=No Displacement=No EdgeSoftening=No ShutLining=No Thickening=No TextureMapping=No AttributeUserText=No _Enter +mpaMatchPropertiesAll -MatchProperties _Pause _Pause MatchAll _Enter +rcmgRemapCplaneMultipleGUI -RunPythonScript "Z:\scripts\rhino\RemapCplaneMultipleGUI.py" +esExtractSrf ExtractSrf +ppPlanarSrf PlanarSrf +boolDiffBooleanDifference BooleanDifference +bdBoolenDifference BooleanDifference +bumacfBooleanUnionMergeAllCoplanarFaces BooleanUnion MergeAllCoplanarFaces +hhHide Hide +jmacfJoinMergeAllCoplanarFaces Join MergeAllCoplanarFaces +poclPropertiesObjectColorLayer -Properties Object Color Layer _Enter _Enter +xselXrefSel -RunPythonScript "Z:\scripts\rhino\XrefSel.py" +mv0MoveVertical000 move vertical _Pause 0,0,0 +cisCopyInplaceSellast Copy InPlace SelLast +r3Rotate3D Rotate3D +ChangeMaterial -RunPythonScript "Z:\scripts\rhino\ChangeMaterial.py" +cmChangeMaterial -RunPythonScript "Z:\scripts\rhino\ChangeMaterial.py" +nvgNamedViewGUI -RunPythonScript "Z:\scripts\rhino\NamedViewGUI.py" +scibSelColorInBlocks -RunPythonScript "Z:\scripts\rhino\SelColorInBlocks.py" +smibSelMaterialInBlocks -RunPythonScript "Z:\scripts\rhino\SelMaterialInBlocks.py" +bsBooleanSplit BooleanSplit +CurrentLayer -Layer Current List _Enter +vvLineVertical Line Vertical +eiExtractIsocurve ExtractIsocurve +evtiExportViewportsToImages -RunPythonScript "Z:\scripts\rhino\ExportViewportsToImages.py" +scpivSelClippingPlaneInViewport SelClippingPlaneInViewport +sltSelLayerTree SelLayerTree +bcBlendCrv BlendCrv _Pause _Pause _Enter +vfbVrayShowVFB VrayShowVFB +vsaeVrayShowAssetEditor vrayShowAssetEditor +bboxBoundingBox BoundingBox +ReOpenThisFileWithoutSaving -RunPythonScript "Z:\scripts\rhino\ReOpenThisFileWithoutSaving.py" +macsMergeAllCoplanarSurfaces MergeAllCoplanarSurfaces +mlMatchLayer MatchLayer +ectExtendCameraTarget -RunPythonScript "Z:\scripts\rhino\ExtendCameraTarget.py" +pbdPullBlocksDown -RunPythonScript "Z:\scripts\rhino\PullBlocksDown.py" +XrefRemoveDWG -RunPythonScript "Z:\scripts\rhino\XrefRemoveDWG.py" +sonSetObjectsName -RunPythonScript "Z:\scripts\rhino\SetObjectsName.py" +scpnSetClippingPlanesName -RunPythonScript "Z:\scripts\rhino\SetClippingPlanesName.py" +gnGetNames -RunPythonScript "Z:\scripts\rhino\GetNames.py" +gaonGetAllObjectsNames -RunPythonScript "Z:\scripts\rhino\GetAllObjectsNames.py" +usUnlockSelected UnlockSelected +dacpDisableAllClippingPlanes -RunPythonScript "Z:\scripts\rhino\DisableAllClippingPlanes.py" +pocPropertiesObjectColor -Properties Object Color Object ColorPicker _Enter _Enter +XrefChangePath -RunPythonScript "Z:\scripts\rhino\XrefChangePath.py" +mmMaxViewport MaxViewport +rccgRemapCplaneCopyGUI -RunPythonScript "Z:\scripts\rhino\RemapCplaneCopyGUI.py" +rvgRemapViewGUI -RunPythonScript "Z:\scripts\rhino\RemapViewGUI.py" +bbeBlockEdit BlockEdit +rccgRemapCplaneCopyMultipleGUI -RunPythonScript "Z:\scripts\rhino\RemapCplaneCopyMultipleGUI.py" +BatchMake2D -RunPythonScript "Z:\scripts\rhino\BatchMake2D.py" +sovnSetObjectViewportsName -RunPythonScript "Z:\scripts\rhino\SetObjectViewportsName.py" +atAbsoluteTolerance -RunPythonScript "Z:\scripts\rhino\AbsoluteTolerance.py" +gavpGetActiveViewportParameters -RunPythonScript "Z:\scripts\rhino\GetActiveViewportParameters.py" diff --git a/SafeLayout.rhp b/SafeLayout.rhp new file mode 100644 index 0000000000000000000000000000000000000000..ee349d3ec533bff2ebd09cea97b1a1654fb14349 GIT binary patch literal 41984 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%0A{~40~r2Kdn;>=G_8q6yU-Y0=Azixt%1U>Vv51) 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 literal 0 HcmV?d00001 diff --git a/SaveAsDWGForFiles.py b/SaveAsDWGForFiles.py new file mode 100644 index 0000000..8433c35 --- /dev/null +++ b/SaveAsDWGForFiles.py @@ -0,0 +1,19 @@ +import rhinoscriptsyntax as rs +import subprocess +import os + +if rs.GetDocumentUserText("Child") is None: + dwg_folder_path = rs.BrowseForFolder("Choose folder to save DWGs into") + files = rs.OpenFileNames("Choose files to save as DWG") + for file in files: + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" ' + \ + '/nosplash /runscript="-SetDocumentUserText Child Child ' + \ + '-SetDocumentUserText Export_DWG_folder_path ' + \ + chr(34) + chr(34) + dwg_folder_path + chr(34) + chr(34) + ' ' + \ + '-RunPythonScript (' + __file__ + ') -Exit No" ' + \ + chr(34) + file + chr(34), shell=True) +else: + dwg_folder_path_child = rs.GetDocumentUserText("Export_DWG_folder_path") + rs.Command("-SaveAs " + chr(34) + dwg_folder_path_child + "\\" + \ + os.path.splitext(rs.DocumentName())[0] + ".dwg" + chr(34)) + rs.Command("-Exit No") \ No newline at end of file diff --git a/SelBlockLinked-CANT-FIND-A-WAY-TO-FILTER-OUT.py b/SelBlockLinked-CANT-FIND-A-WAY-TO-FILTER-OUT.py new file mode 100644 index 0000000..1b2954f --- /dev/null +++ b/SelBlockLinked-CANT-FIND-A-WAY-TO-FILTER-OUT.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + + +a=sc.doc.Objects.GetObjectList(Rhino.DocObjects.ObjectType.InstanceReference) + +a[0].SourceArchive + +#temp= [] +#for i in a: +# if i.SourceArchive \ No newline at end of file diff --git a/SelBlockNames.py b/SelBlockNames.py new file mode 100644 index 0000000..e301778 --- /dev/null +++ b/SelBlockNames.py @@ -0,0 +1,17 @@ +import rhinoscriptsyntax as rs +import itertools + +block_names = rs.BlockNames() + +# rs.BlockContainerCount excludes nested blocks, but doesn't work +# in externally linked blocks - WARNING! ">" character can be used +# on filenames in Linux +block_names_not_nested = [block_name for block_name in block_names + if rs.BlockContainerCount(block_name) == 0 + and ">" not in block_name] + +selected_blocks = rs.MultiListBox(sorted(block_names_not_nested)) +block_instances = [rs.BlockInstances(selected_block) for selected_block in selected_blocks] +# https://stackoverflow.com/a/953097 - unpacking lists in python +block_instances_unpacked = list(itertools.chain(*block_instances)) +rs.SelectObjects(block_instances_unpacked) \ No newline at end of file diff --git a/SelClipEnabled.py b/SelClipEnabled.py new file mode 100644 index 0000000..d38d394 --- /dev/null +++ b/SelClipEnabled.py @@ -0,0 +1,26 @@ +# not finished - can't seem to find a way to get ViewIds +# on the clipping planes +# https://developer.rhino3d.com/api/RhinoCommon/html/P_Rhino_Render_ChangeQueue_ClippingPlane_ViewIds.htm + +import Rhino +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def SelClipEnabled(): + selection_settings = Rhino.DocObjects.ObjectEnumeratorSettings() + selection_settings.ObjectTypeFilter = Rhino.DocObjects.ObjectType.ClipPlane + clip_planes_iterator = sc.doc.Objects.GetObjectList(selection_settings) + + # getobjectlist methods yields an iterator that gets exhausted + # line below converts it into an immutable list + clip_planes = list(clip_planes_iterator) + + clip_planes_enabled = [clip_plane.Name for clip_plane in clip_planes + if clip_plane.Name is not None] + + selected_clip_planes_guids = [clip_plane.Id for clip_plane in clip_planes + if clip_plane.Name in selected_clip_planes] + + rs.SelectObjects(selected_clip_planes_guids) + +SelClipEnabled() \ No newline at end of file diff --git a/SelColorInBlocks.py b/SelColorInBlocks.py new file mode 100644 index 0000000..9cb2c8b --- /dev/null +++ b/SelColorInBlocks.py @@ -0,0 +1,40 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +selected_colors = list() + +# get colors of blocks' sub-objects +# looping through all objects due to: https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/12 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + sub_object_ids = object.GetSelectedSubObjects() + if sub_object_ids: + for sub_object_id in sub_object_ids: + sub_object = object.InstanceDefinition.GetObjects()[sub_object_id.Index] + sub_object_color = sub_object.Attributes.DrawColor(sc.doc) + selected_colors.append(sub_object_color) + +# get colors of other objects +for object_id in rs.SelectedObjects(): + object = rs.coercerhinoobject(object_id) + object_color = object.Attributes.DrawColor(sc.doc) + selected_colors.append(object_color) + +def _SelColor(object): + for sub_object_id, sub_object in enumerate(object.InstanceDefinition.GetObjects()): + if type(sub_object) == Rhino.DocObjects.InstanceObject: + _SelColor(sub_object) + if sub_object.Attributes.DrawColor(sc.doc) in selected_colors: + object.SelectSubObject(Rhino.Geometry.ComponentIndex(Rhino.Geometry.ComponentIndexType.InstanceDefinitionPart, sub_object_id), True, True, True) + +# select objects by color recursively, even though doesn't work for nested blocks +# https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/13 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + _SelColor(object) + if object.Attributes.DrawColor(sc.doc) in selected_colors: + object.Select(on=True) + +rs.EnableRedraw() +rs.Redraw() diff --git a/SelEntireObjLayerTree.py b/SelEntireObjLayerTree.py new file mode 100644 index 0000000..915a8a7 --- /dev/null +++ b/SelEntireObjLayerTree.py @@ -0,0 +1,32 @@ +import rhinoscriptsyntax as rs +import Rhino +""" +Gets selected objects' layers,then selects all objects on those layers plus all +other layers in the layer tree recursively - i.e. selects objects on layers both +"up" and "down" the tree. Script by Mitch Heynick 17.12.18""" + +def GetTopLevelLayer(layer): + parent=rs.ParentLayer(layer) + if parent: layer=GetTopLevelLayer(parent) + return layer + +def SelObjsLayerAndSubs(layer): + rs.ObjectsByLayer(layer, True) + subLayers = rs.LayerChildren(layer) + if(subLayers): + #layer has one or more sublayers + for sLayer in subLayers: + #recurse + SelObjsLayerAndSubs(sLayer) + +def SelEntireObjLayerTree(): + objs=rs.GetObjects("Select objects",preselect=True,select=True) + if not objs: return + layers=set() + for obj in objs: + layers.add(GetTopLevelLayer(rs.ObjectLayer(obj))) + rs.EnableRedraw(False) + for layer in layers: + SelObjsLayerAndSubs(layer) + +SelEntireObjLayerTree() \ No newline at end of file diff --git a/SelHatchPattern-TRY-ME.py b/SelHatchPattern-TRY-ME.py new file mode 100644 index 0000000..c2048fc --- /dev/null +++ b/SelHatchPattern-TRY-ME.py @@ -0,0 +1,55 @@ +import Rhino +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def SelHatchPattern(): + ids = rs.ObjectsByType(65536, state=1) + if not ids: + print "No hatches found" + return + + h = sc.doc.HatchPatterns + selIdx = None + names = [item.Name for item in h] + + go = Rhino.Input.Custom.GetObject() + go.GeometryFilter = Rhino.DocObjects.ObjectType.Hatch + go.SetCommandPrompt("Select hatch objects or type a hatch pattern name inside double quotes.") + go.AddOption("ListPatterns") + + go.AcceptString(True) + + rc = go.GetMultiple(1,0) + + if go.CommandResult() != Rhino.Commands.Result.Success: + return + if rc == Rhino.Input.GetResult.Option: + selNames = rs.CheckListBox([(name,False) for name in names]) + if not selNames: return + selNames = [item[0].lower() for item in selNames if item[1]] + + elif rc == Rhino.Input.GetResult.String: + nameString = go.StringResult() + if not nameString: return + nameList= nameString.Split(",") + selNames= [name.lower() for name in nameList] + + elif rc == Rhino.Input.GetResult.Object: + selIdx = [go.Object(n).Object().HatchGeometry.PatternIndex for n in range (go.ObjectCount)] + + if selIdx is None: + selIdx = [] + for n in range(h.Count): + if h[n].Name.lower() in selNames: + selIdx.append(h[n].Index) + + indices = [rs.coercerhinoobject(id).HatchGeometry.PatternIndex for id in ids] + + rs.EnableRedraw(False) + for n in range(len(indices)): + if indices[n] in selIdx: + rs.SelectObject(ids[n]) + rs.EnableRedraw(True) + + +if __name__ == '__main__':SelHatchPattern() \ No newline at end of file diff --git a/SelLastN-FINISH-ME.py b/SelLastN-FINISH-ME.py new file mode 100644 index 0000000..d2850c2 --- /dev/null +++ b/SelLastN-FINISH-ME.py @@ -0,0 +1,13 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + + +aa=rs.LastObject() +#a=rs.GetObject(preselect=True) +b=rs.coercerhinoobject(aa) + +c=sc.doc.Objects.AllObjectsSince(b.RuntimeSerialNumber) + +print(type(c)) + +#[i.Select(True) for i in c[:2]] diff --git a/SelLayerTree.py b/SelLayerTree.py new file mode 100644 index 0000000..4d44582 --- /dev/null +++ b/SelLayerTree.py @@ -0,0 +1,32 @@ +import rhinoscriptsyntax as rs +import Rhino +"""Script written by Mitch Heynick version 02.07.15 +Selects objects on chosen layers plus all nested sublayers +GetLayers() method is not yet implemented for Mac Rhino - +so choice is limited to a single layer with GetLayer() for the moment""" +def OnMac(): + return Rhino.Runtime.HostUtils.RunningOnOSX + +def SelObjsLayerAndSubs(layer): + rs.ObjectsByLayer(layer, True) + subLayers = rs.LayerChildren(layer) + if(subLayers): + #layer has one or more sublayers + for sLayer in subLayers: + #recurse + SelObjsLayerAndSubs(sLayer) + +def SelLayerTree(): + if OnMac(): + layer=rs.GetLayer("Select layer for objects") + if not layer: return + layers=[layer] + else: + layers = rs.GetLayers("Select layers for objects") + if not(layers): return + rs.EnableRedraw(False) + rs.UnselectAllObjects() + for pLayer in layers: + SelObjsLayerAndSubs(pLayer) + +SelLayerTree() \ No newline at end of file diff --git a/SelMaterialInBlocks.py b/SelMaterialInBlocks.py new file mode 100644 index 0000000..9d80009 --- /dev/null +++ b/SelMaterialInBlocks.py @@ -0,0 +1,42 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +selected_materials = list() + +# get materials of blocks' sub-objects +# looping through all objects due to: https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/12 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + sub_object_ids = object.GetSelectedSubObjects() + if sub_object_ids: + for sub_object_id in sub_object_ids: + sub_object = object.InstanceDefinition.GetObjects()[sub_object_id.Index] + if sub_object.RenderMaterial: + sub_object_material = sub_object.RenderMaterial.Id + selected_materials.append(sub_object_material) + +# get materials of other objects +for object_id in rs.SelectedObjects(): + object = rs.coercerhinoobject(object_id) + if object.RenderMaterial: + object_material = object.RenderMaterial.Id + selected_materials.append(object_material) + +def _SelMaterial(object): + for sub_object_id, sub_object in enumerate(object.InstanceDefinition.GetObjects()): + if type(sub_object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(sub_object) + if sub_object.RenderMaterial and sub_object.RenderMaterial.Id in selected_materials: + object.SelectSubObject(Rhino.Geometry.ComponentIndex(Rhino.Geometry.ComponentIndexType.InstanceDefinitionPart, sub_object_id), True, True, True) + +# select objects by material recursively, even though doesn't work for nested blocks +# https://discourse.mcneel.com/t/let-selcolor-command-select-objects-inside-blocks/151883/13 +for object in sc.doc.Objects: + if type(object) == Rhino.DocObjects.InstanceObject: + _SelMaterial(object) + if object.RenderMaterial and object.RenderMaterial.Id in selected_materials: + object.Select(on=True) + +rs.EnableRedraw() +rs.Redraw() \ No newline at end of file diff --git a/SelObjLayerTree1.py b/SelObjLayerTree1.py new file mode 100644 index 0000000..9f892a3 --- /dev/null +++ b/SelObjLayerTree1.py @@ -0,0 +1,31 @@ +import rhinoscriptsyntax as rs +import Rhino +""" +Gets selected objects' layers,then selects all objects on those layers plus all +other layers in the layer tree recursively - i.e. selects objects on layers both +"up" and "down" the tree. Script by Mitch Heynick 17.12.18""" + +def GetTopLevelLayer(layer): + parent=rs.ParentLayer(layer) + return parent + +def SelObjsLayerAndSubs(layer): + rs.ObjectsByLayer(layer, True) + subLayers = rs.LayerChildren(layer) + if(subLayers): + #layer has one or more sublayers + for sLayer in subLayers: + #recurse + SelObjsLayerAndSubs(sLayer) + +def SelEntireObjLayerTree(): + objs=rs.GetObjects("Select objects",preselect=True,select=True) + if not objs: return + layers=set() + for obj in objs: + layers.add(GetTopLevelLayer(rs.ObjectLayer(obj))) + rs.EnableRedraw(False) + for layer in layers: + SelObjsLayerAndSubs(layer) + +SelEntireObjLayerTree() \ No newline at end of file diff --git a/SelObjLayerTree2.py b/SelObjLayerTree2.py new file mode 100644 index 0000000..55a0c89 --- /dev/null +++ b/SelObjLayerTree2.py @@ -0,0 +1,32 @@ +import rhinoscriptsyntax as rs +import Rhino +""" +Gets selected objects' layers,then selects all objects on those layers plus all +other layers in the layer tree recursively - i.e. selects objects on layers both +"up" and "down" the tree. Script by Mitch Heynick 17.12.18""" + +def GetTopLevelLayer(layer): + parent=rs.ParentLayer(layer) + parent2=rs.ParentLayer(parent) + return parent2 + +def SelObjsLayerAndSubs(layer): + rs.ObjectsByLayer(layer, True) + subLayers = rs.LayerChildren(layer) + if(subLayers): + #layer has one or more sublayers + for sLayer in subLayers: + #recurse + SelObjsLayerAndSubs(sLayer) + +def SelEntireObjLayerTree(): + objs=rs.GetObjects("Select objects",preselect=True,select=True) + if not objs: return + layers=set() + for obj in objs: + layers.add(GetTopLevelLayer(rs.ObjectLayer(obj))) + rs.EnableRedraw(False) + for layer in layers: + SelObjsLayerAndSubs(layer) + +SelEntireObjLayerTree() \ No newline at end of file diff --git a/SelObjectsLayer-1-mine.py b/SelObjectsLayer-1-mine.py new file mode 100644 index 0000000..3725964 --- /dev/null +++ b/SelObjectsLayer-1-mine.py @@ -0,0 +1,16 @@ +import scriptcontext as sc +import rhinoscriptsyntax as rs + +ids = rs.SelectedObjects() + +layers = [rs.ObjectLayer(id) for id in ids] +layers = list(set(layers)) + +for layer in layers: + parent = rs.ParentLayer(layer) + while parent is not None: + rs.ExpandLayer(parent, True) + parent = rs.ParentLayer(parent) + +layers = [sc.doc.Layers.FindByFullPath(layer, -1) for layer in layers] +sc.doc.Layers.Select(layers, True) diff --git a/SelObjectsLayer-2-clement.py b/SelObjectsLayer-2-clement.py new file mode 100644 index 0000000..2254e7f --- /dev/null +++ b/SelObjectsLayer-2-clement.py @@ -0,0 +1,15 @@ +import Rhino +import scriptcontext +import rhinoscriptsyntax as rs + +def SelectObjectLayer(): + + obj_id = rs.GetObject("Select Object", False, False) + if not obj_id: return + + rh_obj = rs.coercerhinoobject(obj_id, True, True) + layer_index = rh_obj.Attributes.LayerIndex + + scriptcontext.doc.Layers.Select([layer_index], True) + +SelectObjectLayer() diff --git a/SelParallelPlanes-TEST-ME.py b/SelParallelPlanes-TEST-ME.py new file mode 100644 index 0000000..21188e3 --- /dev/null +++ b/SelParallelPlanes-TEST-ME.py @@ -0,0 +1,37 @@ +import Rhino +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def SelParallelPlanes(): + def filter_planar( rhino_object, geometry, component_index): + + if geometry.Faces[0].UnderlyingSurface().TryGetPlane()[0]: + return True + return False + + id = rs.GetObject('Select a planar surface', filter =8, preselect=True, custom_filter=filter_planar) + if not id: return + + geo = rs.coercegeometry(id) + rc, plane = geo.Faces[0].UnderlyingSurface().TryGetPlane() + vecDir = plane.ZAxis + + ids = rs.ObjectsByType(8,state=1) + if not ids or len(ids) == 1: + print('No more planar surfaces found') + return + + rs.EnableRedraw(False) + count = 0 + for id in ids: + geo = rs.coercegeometry(id) + rc, plane = geo.Faces[0].UnderlyingSurface().TryGetPlane() + + if rc: + if plane.ZAxis.IsParallelTo(vecDir) != 0: + rs.SelectObject(id) + count += 1 + print(str(count-1) + ' parallel planes selected.') + rs.EnableRedraw(True) + +if __name__ == '__main__':SelParallelPlanes() \ No newline at end of file diff --git a/SelectByCentralNormal.rvb b/SelectByCentralNormal.rvb new file mode 100644 index 0000000..a68bea1 --- /dev/null +++ b/SelectByCentralNormal.rvb @@ -0,0 +1,29 @@ +-runscript ( +sub SelectByCentralNormal + +Dim arrObjects, strObject +objs = Rhino.AllObjects +If IsArray(objs) Then +Rhino.UnselectAllObjects() +For Each obj In objs + + +' SURFACE CASE +if Rhino.IsSurface(obj) then +surf = obj +UV = Rhino.SurfaceParameter (surf , Array(0.5,0.5)) +normal = Rhino.SurfaceNormal (surf , UV) +cameraLocs = Rhino.ViewCameraTarget() +vector = Rhino.VectorCreate(cameraLocs(1),cameraLocs(0)) +angle = Rhino.VectorAngle(vector,normal) +if angle>90 then +Rhino.SelectObject(surf) +End If +End If + + +Next +Rhino.ZoomSelected() +End If +End sub +SelectByCentralNormal diff --git a/SelectObjectLayer.py b/SelectObjectLayer.py new file mode 100644 index 0000000..3c1c4f4 --- /dev/null +++ b/SelectObjectLayer.py @@ -0,0 +1,15 @@ +import Rhino +import scriptcontext +import rhinoscriptsyntax as rs + +def SelectObjectLayer(): + + obj_id = rs.GetObjects(preselect=True) + if not obj_id: return + + rh_obj = rs.coercerhinoobject(obj_id, True, True) + layer_index = rh_obj.Attributes.LayerIndex + + scriptcontext.doc.Layers.Select([layer_index], True) + +SelectObjectLayer() \ No newline at end of file diff --git a/SetClippingPlanesName.py b/SetClippingPlanesName.py new file mode 100644 index 0000000..c1ce322 --- /dev/null +++ b/SetClippingPlanesName.py @@ -0,0 +1,21 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def SetClippingPlanesName(): + selected_objects = rs.SelectedObjects() + if selected_objects == None: return + + objects = {i.Name for i in sc.doc.Objects if type(i) == Rhino.DocObjects.ClippingPlaneObject} + + if len(selected_objects) == 1: + message = rs.coercerhinoobject(selected_objects[0]).Name + else: + message="Set Objects Name" + + name = rs.ComboListBox(list(objects), message=message, title="All Named Objects") + if name == None: return + + rs.ObjectName(selected_objects, name) + +SetClippingPlanesName() \ No newline at end of file diff --git a/SetLayerColorsToMatchCTB.py b/SetLayerColorsToMatchCTB.py new file mode 100644 index 0000000..53abca2 --- /dev/null +++ b/SetLayerColorsToMatchCTB.py @@ -0,0 +1,98 @@ +import rhinoscriptsyntax as rs +import re +import System.Drawing.Color + +def SetAllLayerColors(): + for layer in rs.LayerNames(): + layer_name_re = re.search("AR[0-9]+", layer) + if layer_name_re: + ctb_layer_code = layer_name_re.group() + + layer_color_str = ctb_colors[ctb_layer_code] + layer_color = System.Drawing.Color.FromArgb(int(layer_color_str.split(",")[0]), + int(layer_color_str.split(",")[1]), + int(layer_color_str.split(",")[2])) + rs.LayerColor(layer, color=layer_color) + +#codes extracted from template files +ctb_colors={ +"0": "255,255,255", +"AR000": "128,128,128", +"AR001": "192,192,192", +"AR002": "255,255,255", +"AR003": "0,255,255", +"AR004": "192,192,192", +"AR006": "255,127,0", +"AR007": "255,0,0", +"AR008": "255,0,0", +"AR009": "255,127,0", +"AR031": "128,128,128", +"AR035": "128,128,128", +"AR036": "255,0,63", +"AR042": "0,0,0", +"AR061": "255,255,255", +"AR062": "255,0,0", +"AR063": "255,255,255", +"AR070": "0,255,255", +"AR071": "128,128,128", +"AR075": "128,128,128", +"AR169": "0,255,255", +"AR211": "255,0,0", +"AR214": "0,255,255", +"AR216": "0,255,0", +"AR219": "0,255,255", +"AR221": "255,0,0", +"AR229": "128,128,128", +"AR231": "128,128,128", +"AR232": "255,255,0", +"AR237": "255,0,0", +"AR240": "0,255,0", +"AR241": "0,255,0", +"AR272": "255,0,0", +"AR277": "0,255,0", +"AR281": "255,0,0", +"AR282": "0,255,0", +"AR283": "0,255,0", +"AR310": "128,128,128", +"AR314": "0,255,255", +"AR315": "0,255,0", +"AR318": "0,255,255", +"AR319": "255,255,0", +"AR324": "0,255,0", +"AR325": "0,255,0", +"AR340": "0,255,255", +"AR351": "0,255,0", +"AR371": "0,255,0", +"AR413": "255,0,0", +"AR414": "0,255,255", +"AR420": "0,255,0", +"AR431": "192,192,192", +"AR439": "0,255,0", +"AR471": "128,128,128", +"AR520": "128,128,128", +"AR522": "128,128,128", +"AR525": "255,0,0", +"AR610": "255,0,0", +"AR611": "0,255,255", +"AR630": "0,255,255", +"AR640": "128,128,128", +"AR661": "0,255,0", +"AR664": "0,255,255", +"AR680": "128,128,128", +"AR683": "0,255,255", +"AR711": "0,255,255", +"AR731": "0,255,255", +"AR741": "128,128,128", +"AR783": "0,255,255", +"AR785": "128,128,128", +"AR900": "255,255,0", +"AR901": "255,0,0", +"AR902": "255,255,255", +"AR904": "128,128,128", +"AR905": "128,128,128", +"AR906": "128,128,128", +"AR907": "0,255,255", +"AR908": "0,255,255", +"AR910": "128,128,128"} + +SetAllLayerColors() diff --git a/SetLayerColorsToMatchCTBForFiles.py b/SetLayerColorsToMatchCTBForFiles.py new file mode 100644 index 0000000..fbfb44b --- /dev/null +++ b/SetLayerColorsToMatchCTBForFiles.py @@ -0,0 +1,20 @@ +import rhinoscriptsyntax as rs +import os +import subprocess +import System + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Multiselect = True +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + selected_files = dlg.FileNames + +#for selected_file in selected_files: +# subprocess.Popen(["C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe", "/nosplash", +# '/runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\SetLayerColorsToMatchCTB.py) save exit"', +# selected_file], close_fds=True, shell=True) + +for i, selected_file in enumerate(selected_files): + with open(os.environ['TEMP'] + "\\madness" + str(i) + ".cmd", "w") as madness: + madness.write('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\SetLayerColorsToMatchCTB.py) save exit" ' + chr(34) + selected_file + chr(34)) + madness.flush() + subprocess.Popen(madness.name, shell=True) diff --git a/SetLayerPrintWidthsToMatchCTB.py b/SetLayerPrintWidthsToMatchCTB.py new file mode 100644 index 0000000..a584711 --- /dev/null +++ b/SetLayerPrintWidthsToMatchCTB.py @@ -0,0 +1,94 @@ +import rhinoscriptsyntax as rs +import re + + +def SetAllLayerPrintWidths(): + for layer in rs.LayerNames(): + layer_name_re = re.search("AR[0-9]+", layer) + if layer_name_re: + ctb_layer_code = layer_name_re.group() + rs.LayerPrintWidth(layer, width=ctb_printwidths[ctb_layer_code]) + + +# codes extracted from template files +ctb_printwidths = { + "AR000": 0.05, + "AR001": 0.05, + "AR002": 0.05, + "AR003": 0.1, + "AR004": 0.05, + "AR006": 0.05, + "AR007": 0.18, + "AR008": 0.05, + "AR009": 0.05, + "AR031": 0.1, + "AR035": 0.05, + "AR036": 0.05, + "AR042": 0.05, + "AR061": 0.05, + "AR062": 0.05, + "AR063": 0.05, + "AR070": 0.1, + "AR071": 0.05, + "AR075": 0.05, + "AR169": 0.1, + "AR211": 0.18, + "AR214": 0.1, + "AR216": 0.15, + "AR219": 0.1, + "AR221": 0.18, + "AR229": 0.05, + "AR231": 0.05, + "AR232": 0.25, + "AR237": 0.18, + "AR240": 0.15, + "AR241": 0.15, + "AR272": 0.18, + "AR277": 0.15, + "AR281": 0.18, + "AR282": 0.15, + "AR283": 0.15, + "AR310": 0.05, + "AR314": 0.1, + "AR315": 0.15, + "AR318": 0.1, + "AR319": 0.25, + "AR324": 0.15, + "AR325": 0.15, + "AR340": 0.1, + "AR351": 0.15, + "AR371": 0.15, + "AR413": 0.18, + "AR414": 0.1, + "AR420": 0.15, + "AR431": 0.05, + "AR439": 0.15, + "AR471": 0.05, + "AR520": 0.05, + "AR522": 0.05, + "AR525": 0.18, + "AR610": 0.18, + "AR611": 0.1, + "AR630": 0.1, + "AR640": 0.05, + "AR661": 0.15, + "AR664": 0.1, + "AR680": 0.05, + "AR683": 0.1, + "AR711": 0.1, + "AR731": 0.1, + "AR741": 0.05, + "AR783": 0.1, + "AR785": 0.05, + "AR900": 0.25, + "AR901": 2.00, + "AR902": 0.05, + "AR904": 0.05, + "AR905": 0.05, + "AR906": 0.05, + "AR907": 0.1, + "AR908": 0.1, + "AR910": 0.05, +} + +SetAllLayerPrintWidths() diff --git a/SetLayerPrintWidthsToMatchCTBForFiles.py b/SetLayerPrintWidthsToMatchCTBForFiles.py new file mode 100644 index 0000000..a087ead --- /dev/null +++ b/SetLayerPrintWidthsToMatchCTBForFiles.py @@ -0,0 +1,20 @@ +import rhinoscriptsyntax as rs +import os +import subprocess +import System + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Multiselect = True +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + selected_files = dlg.FileNames + +#for selected_file in selected_files: +# subprocess.Popen(["C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe", "/nosplash", +# '/runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\SetLayerPrintWidthsToMatchCTB.py) save exit"', +# selected_file], close_fds=True, shell=True) + +for i, selected_file in enumerate(selected_files): + with open(os.environ['TEMP'] + "\\madness" + str(i) + ".cmd", "w") as madness: + madness.write('start /min "" "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\SetLayerPrintWidthsToMatchCTB.py) save exit" ' + chr(34) + selected_file + chr(34)) + madness.flush() + subprocess.Popen(madness.name, shell=True) diff --git a/SetObjectViewportsName.py b/SetObjectViewportsName.py new file mode 100644 index 0000000..f5da2e2 --- /dev/null +++ b/SetObjectViewportsName.py @@ -0,0 +1,21 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +from Rhino.DocObjects import DetailViewObject + +def SetObjectsName(): + selected_objects = rs.SelectedObjects() + if selected_objects == None: return + + objects_viewports = {i.Name for i in sc.doc.Objects if type(i) == DetailViewObject} + + if len(selected_objects) == 1: + message = rs.coercerhinoobject(selected_objects[0]).Name + else: + message="Set Objects (Viewports) Name" + + name = rs.ComboListBox(sorted(list(objects_viewports)), message=message, title="All Named Objects") + if name == None: return + + rs.ObjectName(selected_objects, name) + +SetObjectsName() \ No newline at end of file diff --git a/SetObjectsName.py b/SetObjectsName.py new file mode 100644 index 0000000..5523191 --- /dev/null +++ b/SetObjectsName.py @@ -0,0 +1,22 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +#import Rhino + +def SetObjectsName(): + selected_objects = rs.SelectedObjects() + if selected_objects == None: return + + objects = {i.Name for i in sc.doc.Objects} + #b = [i for i in sc.doc.Objects if type(i) == Rhino.DocObjects.ClippingPlaneObject] + + if len(selected_objects) == 1: + message = rs.coercerhinoobject(selected_objects[0]).Name + else: + message="Set Objects Name" + + name = rs.ComboListBox(sorted(list(objects)), message=message, title="All Named Objects") + if name == None: return + + rs.ObjectName(selected_objects, name) + +SetObjectsName() \ No newline at end of file diff --git a/ShowLayerInLayoutDetails.py b/ShowLayerInLayoutDetails.py new file mode 100644 index 0000000..d1c7796 --- /dev/null +++ b/ShowLayerInLayoutDetails.py @@ -0,0 +1,41 @@ +__author__ = "Alasdair Mott" +__version__ = "2018.03.15" +# modified 24.11.22 to replace CheckListBox with MultiListBox + +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def hideLayerInLayouts(page): + details = Rhino.Display.RhinoPageView.GetDetailViews(page) + + for i, detail in enumerate(details): + + #rs.CurrentDetail(pageName, detail) + detailId = detail.Id + + for layerString in layers: + + layer_idx = sc.doc.Layers.FindByFullPath(layerString, True) + layer = sc.doc.Layers.FindIndex(layer_idx) + Rhino.DocObjects.Layer.SetPerViewportVisible(layer, detailId, True) + +pageName = rs.CurrentView() +pageNames = rs.ViewNames(True, 1) +pages = sc.doc.Views.GetPageViews() + +""" User Input """ +layers = rs.GetLayers() + +if pageNames and layers: + pageNamesHide = rs.MultiListBox(pageNames, "Layouts to turn off Layer In", "Hide Layer In Layout") + +""" Iterate Pages """ +rs.EnableRedraw(False) +if layers: + if pageNamesHide: + for page in pages: + hideLayerInLayouts(page) +rs.EnableRedraw(True) +rs.Redraw() + diff --git a/ShowLayers.py b/ShowLayers.py new file mode 100644 index 0000000..0154612 --- /dev/null +++ b/ShowLayers.py @@ -0,0 +1,8 @@ +import rhinoscriptsyntax as rs + +def ShowLayers(): + layers=rs.GetLayers() + for layer in layers: + rs.LayerVisible(layer, visible=True) + +ShowLayers() \ No newline at end of file diff --git a/SwitchView.py b/SwitchView.py new file mode 100644 index 0000000..5638a8d --- /dev/null +++ b/SwitchView.py @@ -0,0 +1,6 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +scriptcontext.doc.Views.ActiveView +rs.CurrentView() +a \ No newline at end of file diff --git a/Tags-ClearTagObjects.py b/Tags-ClearTagObjects.py new file mode 100644 index 0000000..f7d74b2 --- /dev/null +++ b/Tags-ClearTagObjects.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs + +def ClearTagObjects(): + + ids = rs.AllObjects() + + if not ids: return + + for id in ids: + rs.SetUserText(id, 'FileTag', "") + +ClearTagObjects() \ No newline at end of file diff --git a/Tags-SelTagObjects.py b/Tags-SelTagObjects.py new file mode 100644 index 0000000..1cea5a8 --- /dev/null +++ b/Tags-SelTagObjects.py @@ -0,0 +1,22 @@ +import rhinoscriptsyntax as rs + +def SelTagObjects(): + + file = rs.DocumentName() + + if not file:return + + tagString = file.split(".")[0] + + ids = rs.NormalObjects() + + if not ids: return + rs.UnselectAllObjects() + rs.EnableRedraw(False) + + for id in ids: + if rs.SetUserText(id, 'FileTag', tagString): + rs.SelectObject(id) + rs.EnableRedraw(True) + +SelTagObjects() \ No newline at end of file diff --git a/Tags-TagObjects.py b/Tags-TagObjects.py new file mode 100644 index 0000000..dfc9143 --- /dev/null +++ b/Tags-TagObjects.py @@ -0,0 +1,18 @@ +import rhinoscriptsyntax as rs + +def TagObjects(): + + file = rs.DocumentName() + + if not file:return + + tagString = file.split(".")[0] + + ids = rs.AllObjects() + + if not ids: return + + for id in ids: + rs.SetUserText(id, 'FileTag', tagString) + +TagObjects() \ No newline at end of file diff --git a/TestMake2D.py b/TestMake2D.py new file mode 100644 index 0000000..5833184 --- /dev/null +++ b/TestMake2D.py @@ -0,0 +1,68 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def TestMake2D(): + msg="Select objects to draw" + #check object collections + objIDs=rs.GetObjects(msg,8+16,preselect=True) + if not objIDs: return + + objs=[sc.doc.Objects.Find(objID).Geometry for objID in objIDs] + +# #Artificially set a top view projection (no viewport needed) +# bb=rs.BoundingBox(objIDs) +# rot_pt=(bb[0]+bb[6])/2 +# ht=bb[4].Z-bb[0].Z +# z_vec=Rhino.Geometry.Vector3d.ZAxis +# vp=Rhino.Display.RhinoViewport() +# vp.ChangeToParallelProjection(True) +# vp.SetCameraTarget(rot_pt-(z_vec*ht),False) +# vp.SetCameraLocation(rot_pt+z_vec*ht,False) + + #get Top viewport from standard Rhino views + for view in sc.doc.Views.GetStandardRhinoViews(): + if view.MainViewport.Name=="Top": + vp=view.MainViewport + break + + #Create the Make2D drawing + hdp=Rhino.Geometry.HiddenLineDrawingParameters() + [hdp.AddGeometry(obj,"") for obj in objs] + hdp.SetViewport(vp) + hld=Rhino.Geometry.HiddenLineDrawing.Compute(hdp,True) + if hld: + crvs=[] + vis=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Visible + hid=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Hidden + proj=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Projecting + dup=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Duplicate + clip=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Clipped + uns=Rhino.Geometry.HiddenLineDrawingSegment.Visibility.Unset + + rs.EnableRedraw(False) + for i,seg in enumerate(hld.Segments): + print "Segment {} Type:{}".format(i,seg.SegmentVisibility) + if not seg.SegmentVisibility == vis: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Visible") + elif seg.SegmentVisibility == hid: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Hidden") + elif seg.SegmentVisibility == proj: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Projecting") + elif seg.SegmentVisibility == dup: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Duplicate") + elif seg.SegmentVisibility == clip: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Clipped") + elif seg.SegmentVisibility == uns: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Unset") + else: + crvID=sc.doc.Objects.AddCurve(seg.CurveGeometry) + rs.ObjectLayer(crvID,"Unknown") + sc.doc.Views.Redraw() +TestMake2D() diff --git a/UpdateAllChangedBlocks.py b/UpdateAllChangedBlocks.py new file mode 100644 index 0000000..4e52dd7 --- /dev/null +++ b/UpdateAllChangedBlocks.py @@ -0,0 +1,14 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def UpdateAllChangedBlocks(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + linked_blocks=[i for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + for linked_block in linked_blocks: + if rs.BlockStatus(linked_block.Name) == 1: + sc.doc.InstanceDefinitions.RefreshLinkedBlock(linked_block) + +UpdateAllChangedBlocks() \ No newline at end of file diff --git a/XrefChangePath.py b/XrefChangePath.py new file mode 100644 index 0000000..25b6138 --- /dev/null +++ b/XrefChangePath.py @@ -0,0 +1,27 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import System +import Rhino +import os + +block_guids = rs.GetObjects(preselect=True) + +block_names = list() +for block_guid in block_guids: + block_names.append(rs.BlockInstanceName(block_guid)) + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Title = " and ".join(block_names) +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + file_location = dlg.FileName + +for block_guid in block_guids: + block_obj = rs.coercerhinoobject(block_guid) + block_idx = block_obj.InstanceDefinition.Index + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_idx, + file_location, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 1) + block_file_name = os.path.basename(os.path.splitext(block_obj.InstanceDefinition.SourceArchive)[0]) + rs.RenameBlock(block_obj.InstanceDefinition.Name, block_file_name) \ No newline at end of file diff --git a/XrefChangePathList-WIP.py b/XrefChangePathList-WIP.py new file mode 100644 index 0000000..e42b13d --- /dev/null +++ b/XrefChangePathList-WIP.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def XrefChangePath(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + linked_blocks=[i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + selected_blocks = rs.MultiListBox(linked_blocks) + for linked_block in selected_blocks: + test=rs.OpenFileName("test") +# sc.doc.InstanceDefinitions.ModifySourceArchive( + +XrefChangePath() \ No newline at end of file diff --git a/XrefChangePathWithoutRenaming.py b/XrefChangePathWithoutRenaming.py new file mode 100644 index 0000000..9ab6a0f --- /dev/null +++ b/XrefChangePathWithoutRenaming.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import System +import Rhino +import os + +block_guids = rs.GetObjects(preselect=True) + +block_names = list() +for block_guid in block_guids: + block_names.append(rs.BlockInstanceName(block_guid)) + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Title = " and ".join(block_names) +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + file_location = dlg.FileName + +for block_guid in block_guids: + block_obj = rs.coercerhinoobject(block_guid) + block_idx = block_obj.InstanceDefinition.Index + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_idx, + file_location, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 1) \ No newline at end of file diff --git a/XrefConvertCurvesToLinesForFiles.py b/XrefConvertCurvesToLinesForFiles.py new file mode 100644 index 0000000..33eed3f --- /dev/null +++ b/XrefConvertCurvesToLinesForFiles.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import subprocess +import os + +if rs.GetDocumentUserText("Child") is None: + files = rs.OpenFileNames("choose files to convert curves to lines") + for file in files: + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" ' + \ + '/nosplash /runscript="-SetDocumentUserText Child Child ' + \ + '-RunPythonScript (' + __file__ + ')" ' + \ + chr(34) + file + chr(34), shell=True) +else: + rs.Command("_SelLine") + rs.Command("_Convert Output=Lines SimplifyInput=No DeleteInput=Yes OutputLayer=Input _Enter") + rs.Command("Save") + rs.Command("Exit") \ No newline at end of file diff --git a/XrefCreateProxies.py b/XrefCreateProxies.py new file mode 100644 index 0000000..a40e6dd --- /dev/null +++ b/XrefCreateProxies.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs +import subprocess +import os + +if rs.GetDocumentUserText("Child") is None: + files = rs.OpenFileNames("choose files to create proxies") + for file in files: + subprocess.Popen('start "" /min "C:\\Program Files\\Rhino 8 WIP\\System\\Rhino.exe" /nosplash /runscript="-SetDocumentUserText Child Child -RunPythonScript (G:\\0000 CAD LIBRARY\\Scripts\\rhino\\CreateProxies.py) -Exit No" ' + chr(34) + file + chr(34), shell=True) +else: + rs.Command("SelSmall 4000") + rs.Command("SelBlockInstance") + rs.Command("Delete") + rs.Command("-Purge _Enter") + rs.Command("-SaveAs " + chr(34) + rs.DocumentPath() + "\\proxy\\" + os.path.splitext(rs.DocumentName())[0] + "-proxy" + chr(34)) + rs.Command("Exit") \ No newline at end of file diff --git a/XrefExportSeparateAsDWG.py b/XrefExportSeparateAsDWG.py new file mode 100644 index 0000000..33ed77b --- /dev/null +++ b/XrefExportSeparateAsDWG.py @@ -0,0 +1,45 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import itertools +import os + +folder = rs.BrowseForFolder("Select Folder to export xref instances") + +# allow for custom prefix in file name +# if doesn't exist in the list append it and save it in the Document's User Text +file_name_prefix_list_str = rs.GetDocumentUserText("File-Name-Prefix-List") +if file_name_prefix_list_str is None: + file_name_prefix_list_str = rs.ComboListBox(["None"], message="Add File Name Prefix") + rs.SetDocumentUserText("File-Name-Prefix-List", file_name_prefix_list_str) + selected_prefix = "" +else: + file_name_prefix_list = file_name_prefix_list_str.split(",") + selected_prefix = rs.ComboListBox(file_name_prefix_list) + file_name_prefix_list_new = list(set(file_name_prefix_list.append(selected_prefix))) + file_name_prefix_list_new_str = ",".join(file_name_prefix_list_new) + rs.SetDocumentUserText("File-Name-Prefix-List", file_name_prefix_list_str) + +block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) +block_definitions_list = list(block_definitions) + +# rs.BlockContainerCount excludes nested blocks, but doesn't work +# in externally linked blocks - WARNING! ">" character can be used +# on filenames in Linux +xrefs = [i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False + and rs.BlockContainerCount(i.Name) == 0 + and ">" not in i.Name] + +selected_xrefs = rs.MultiListBox(sorted(xrefs)) +xref_instances = [rs.BlockInstances(selected_xref) for selected_xref in selected_xrefs] +# https://stackoverflow.com/a/953097 - unpacking lists in python +xref_instances_unpacked = list(itertools.chain(*xref_instances)) +for xref_instance in xref_instances_unpacked: + rs.Command("SelNone") + rs.SelectObject(xref_instance) + block_name = rs.coercerhinoobject(xref_instance).InstanceDefinition.Name +# document_name = "Untitled" +# if rs.DocumentName(): +# document_name, document_ext = os.path.splitext(rs.DocumentName()) + rs.Command("-Export " + chr(34) + folder + os.path.sep + selected_prefix + block_name + ".dwg" + chr(34)) + rs.Command("SelNone") \ No newline at end of file diff --git a/XrefExportWithModelBasePoint.py b/XrefExportWithModelBasePoint.py new file mode 100644 index 0000000..1954b64 --- /dev/null +++ b/XrefExportWithModelBasePoint.py @@ -0,0 +1,42 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino +import os + +# get folder +xref_export_stash = rs.GetDocumentData("Xrefs", "Folder") +if xref_export_stash is None: + xref_export_stash = rs.BrowseForFolder(message="choose location to stash xrefs - once chosen won't prompt for it again") + rs.SetDocumentData("Xrefs", "Folder", xref_export_stash) + +# get doc name but check if it's an "Untitled" aka not yet saved document +rhino_doc_name = rs.DocumentName() +if rhino_doc_name: + rhino_doc_name = os.path.splitext(rhino_doc_name)[0] + +# get prefix +xref_prefix_set_str = rs.GetDocumentData("Xrefs", "Prefix") + +if xref_prefix_set_str: + xref_prefix_set = set(xref_prefix_set_str.split("--||--")) +else: + xref_prefix_set = set() + xref_prefix_set.add("0") + +selected_xref_prefix = rs.ComboListBox(sorted(xref_prefix_set), message="Choose Xref Prefix") +xref_prefix_set.add(selected_xref_prefix) +rs.SetDocumentData("Xrefs", "Prefix", "--||--".join(xref_prefix_set)) + +# get Cplane +named_cplanes = sc.doc.NamedConstructionPlanes +selected_cplane = rs.ComboListBox([i.Name for i in named_cplanes], "Named CPlanes") + +xref_file_name = xref_export_stash + os.path.sep + rhino_doc_name + " - " + selected_xref_prefix + " - " + selected_cplane + +for named_cplane in named_cplanes: + if named_cplane.Name == selected_cplane: + sc.doc.ModelBasepoint = named_cplane.Plane.Origin + +rs.Command("-Export " + chr(34) + xref_file_name + chr(34)) + +sc.doc.ModelBasepoint = Rhino.Geometry.Point3d(0,0,0) \ No newline at end of file diff --git a/XrefFilePaths.py b/XrefFilePaths.py new file mode 100644 index 0000000..e94de48 --- /dev/null +++ b/XrefFilePaths.py @@ -0,0 +1,14 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +block_ids = rs.GetObjects(filter=4096, preselect=True) + +if block_ids: + block_paths = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_path = rs.BlockPath(block_name) + block_paths.append(block_path) + Rhino.UI.Dialogs.ShowTextDialog("\n".join(block_paths), "Selected Block Paths") +# rs.ComboListBox(block_paths) \ No newline at end of file diff --git a/XrefFilePathsSet.py b/XrefFilePathsSet.py new file mode 100644 index 0000000..c8cc4dd --- /dev/null +++ b/XrefFilePathsSet.py @@ -0,0 +1,17 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +def GetPathSetBlocks(): + block_ids = rs.GetObjects(filter=4096, preselect=True) + + if block_ids: + block_paths = list() + for block_id in block_ids: + block_name = rs.BlockInstanceName(block_id) + block_path = rs.BlockPath(block_name) + block_paths.append(block_path) + Rhino.UI.Dialogs.ShowTextDialog("\n".join(sorted(set(list(block_paths)))), "Selected Block Paths") +# rs.ComboListBox(sorted(set(list(block_paths)))) + +GetPathSetBlocks() \ No newline at end of file diff --git a/XrefHide.py b/XrefHide.py new file mode 100644 index 0000000..48c89a5 --- /dev/null +++ b/XrefHide.py @@ -0,0 +1,12 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +layer_names = rs.LayerNames() +xref_layers = [i.replace('xref-AR000::', '') for i in layer_names if "xref-AR000::" in i] +selected_layers = rs.MultiListBox(xref_layers) + +for layer_short_name in selected_layers: + layer_index = sc.doc.Layers.FindByFullPath('xref-AR000::' + layer_short_name, + notFoundReturnValue=False) + layer_object = sc.doc.Layers.FindIndex(layer_index) + layer_object.IsVisible = False \ No newline at end of file diff --git a/XrefHideBlocks.py b/XrefHideBlocks.py new file mode 100644 index 0000000..f666ea6 --- /dev/null +++ b/XrefHideBlocks.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def XrefHideBlocks(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + linked_blocks=[i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + selection_names = rs.MultiListBox(sorted(linked_blocks)) + selection_instances = list() + for selection_name in selection_names: + selection_instances.append(rs.BlockInstances(selection_name)) + rs.HideObjects(selection_instances) + +XrefHideBlocks() \ No newline at end of file diff --git a/XrefInsertInTheSamePlace.py b/XrefInsertInTheSamePlace.py new file mode 100644 index 0000000..e4c0a6b --- /dev/null +++ b/XrefInsertInTheSamePlace.py @@ -0,0 +1,21 @@ +# takes into account blocks that have ModelBasePoint other than 0,0,0 +# 22.11.22 updated to insert other formats than 3dm +# you forgot to restore the previous CPlane +import Rhino +import rhinoscriptsyntax as rs +import os + +xref_file_names = rs.OpenFileNames() +for xref_file_name in xref_file_names: + xref_file_basename, xref_file_ext = os.path.splitext(xref_file_name) + if xref_file_ext == ".3dm": + model_base_point = Rhino.FileIO.File3dm.Read(xref_file_name).Settings.ModelBasepoint + rs.Command('-Cplane World Top -Insert LinkMode=Link LinkStyle=Reference "{}" Block {} 1 0'.format(xref_file_name, str(model_base_point))) + rs.Command('SelLast') + if xref_file_ext == ".dwg": + rs.Command('-Cplane World Top -Insert LinkMode=Link LinkStyle=Reference "{}" Block _Enter 0,0,0 1 0'.format(xref_file_name)) + rs.Command('SelLast') + # not tested yet - use with caution + else: + rs.Command('-Cplane World Top -Insert LinkMode=Link LinkStyle=Reference "{}" Block 0,0,0 1 0'.format(xref_file_name)) + rs.Command('SelLast') \ No newline at end of file diff --git a/XrefLayersHideAndBlocks.py b/XrefLayersHideAndBlocks.py new file mode 100644 index 0000000..87b82f6 --- /dev/null +++ b/XrefLayersHideAndBlocks.py @@ -0,0 +1,17 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def GetXrefLayers(): + a=rs.LayerNames() + b=[i.replace('xref-AR000::', '') for i in a if "xref-AR000::" in i] + c=rs.MultiListBox(b) + return c + +def XrefLayersHideAndBlocks(): + layers = GetXrefLayers() + for layer in layers: + objects = sc.doc.Objects.FindByLayer(layer) + rs.HideObjects(objects) + rs.LayerVisible(layer, visible=False) + +XrefLayersHideAndBlocks() \ No newline at end of file diff --git a/XrefModifyPath.py b/XrefModifyPath.py new file mode 100644 index 0000000..25b6138 --- /dev/null +++ b/XrefModifyPath.py @@ -0,0 +1,27 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import System +import Rhino +import os + +block_guids = rs.GetObjects(preselect=True) + +block_names = list() +for block_guid in block_guids: + block_names.append(rs.BlockInstanceName(block_guid)) + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Title = " and ".join(block_names) +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + file_location = dlg.FileName + +for block_guid in block_guids: + block_obj = rs.coercerhinoobject(block_guid) + block_idx = block_obj.InstanceDefinition.Index + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_idx, + file_location, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 1) + block_file_name = os.path.basename(os.path.splitext(block_obj.InstanceDefinition.SourceArchive)[0]) + rs.RenameBlock(block_obj.InstanceDefinition.Name, block_file_name) \ No newline at end of file diff --git a/XrefModifyPathList-WIP.py b/XrefModifyPathList-WIP.py new file mode 100644 index 0000000..e42b13d --- /dev/null +++ b/XrefModifyPathList-WIP.py @@ -0,0 +1,15 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def XrefChangePath(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + linked_blocks=[i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + selected_blocks = rs.MultiListBox(linked_blocks) + for linked_block in selected_blocks: + test=rs.OpenFileName("test") +# sc.doc.InstanceDefinitions.ModifySourceArchive( + +XrefChangePath() \ No newline at end of file diff --git a/XrefModifyPathWithoutRenaming.py b/XrefModifyPathWithoutRenaming.py new file mode 100644 index 0000000..9ab6a0f --- /dev/null +++ b/XrefModifyPathWithoutRenaming.py @@ -0,0 +1,25 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import System +import Rhino +import os + +block_guids = rs.GetObjects(preselect=True) + +block_names = list() +for block_guid in block_guids: + block_names.append(rs.BlockInstanceName(block_guid)) + +dlg = System.Windows.Forms.OpenFileDialog() +dlg.Title = " and ".join(block_names) +if dlg.ShowDialog()==System.Windows.Forms.DialogResult.OK: + file_location = dlg.FileName + +for block_guid in block_guids: + block_obj = rs.coercerhinoobject(block_guid) + block_idx = block_obj.InstanceDefinition.Index + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_idx, + file_location, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 1) \ No newline at end of file diff --git a/XrefModifyUpdateType-without-editing.py b/XrefModifyUpdateType-without-editing.py new file mode 100644 index 0000000..0bbffb7 --- /dev/null +++ b/XrefModifyUpdateType-without-editing.py @@ -0,0 +1,54 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino +import time + +block_id = rs.GetObject(filter=4096, preselect=True) +block_definition = rs.coercerhinoobject(block_id).InstanceDefinition + +update_type = rs.ComboListBox(["Embedded", "Linked"], "Change Block Update Type to:") +if update_type == "Embedded" and \ +block_definition.UpdateType == Rhino.DocObjects.InstanceDefinitionUpdateType.Linked: + if rs.SetUserText(block_id, key="SourceArchive", + value=block_definition.SourceArchive): + sc.doc.InstanceDefinitions.ModifySourceArchive(block_definition.Index, + block_definition.SourceArchive, + Rhino.DocObjects.InstanceDefinitionUpdateType.Static, + quiet=1) + rs.SelectObject(block_id) + rs.Command("BlockEdit") + +# use Static instead of Embedded +# Rhino will default to Static even if Embedded was set in ModifySourceArchive function +# https://github.com/mcneel/rhinocommon/blob/master/dotnet/rhino/rhinosdkinstance.cs#L23 +if update_type == "Linked" and \ +block_definition.UpdateType == Rhino.DocObjects.InstanceDefinitionUpdateType.Static: + # you can't store user text on block definition + # and I'd rather not use the description field + # so store it on the first block instance user clicked and + # iterate through all of them (hoping that wasn't deleted) + # don't want to store it in document, because the block may be renamed/reinserted + # https://discourse.mcneel.com/t/can-you-add-user-text-to-block-definition/150530 + for block_instance_id in rs.BlockInstances(block_definition.Name): + block_instance_source_archive = rs.GetUserText(block_instance_id, key="SourceArchive") + if block_instance_source_archive: + model_base_point = Rhino.FileIO.File3dm.Read(block_instance_source_archive).Settings.ModelBasepoint + sc.doc.ModelBasepoint = model_base_point + rs.Command("-Cplane World Top") + rs.Command("-Insert File=No " + chr(34) + block_definition.Name + chr(34) + " Block " + str(model_base_point) + " 1 0") + rs.Command("SelLast") + rs.Command("Explode") + rs.Command("-Export " + chr(34) + block_instance_source_archive + chr(34)) + rs.Command("Delete") + sc.doc.ModelBasepoint = Rhino.Geometry.Point3d(0,0,0) + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_definition.Index, + block_instance_source_archive, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + quiet=1) + + rs.SelectObject(block_id) + + # use the first one found - problably should + # add extra checks in case there are multiple paths + break \ No newline at end of file diff --git a/XrefModifyUpdateType.py b/XrefModifyUpdateType.py new file mode 100644 index 0000000..0bbffb7 --- /dev/null +++ b/XrefModifyUpdateType.py @@ -0,0 +1,54 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino +import time + +block_id = rs.GetObject(filter=4096, preselect=True) +block_definition = rs.coercerhinoobject(block_id).InstanceDefinition + +update_type = rs.ComboListBox(["Embedded", "Linked"], "Change Block Update Type to:") +if update_type == "Embedded" and \ +block_definition.UpdateType == Rhino.DocObjects.InstanceDefinitionUpdateType.Linked: + if rs.SetUserText(block_id, key="SourceArchive", + value=block_definition.SourceArchive): + sc.doc.InstanceDefinitions.ModifySourceArchive(block_definition.Index, + block_definition.SourceArchive, + Rhino.DocObjects.InstanceDefinitionUpdateType.Static, + quiet=1) + rs.SelectObject(block_id) + rs.Command("BlockEdit") + +# use Static instead of Embedded +# Rhino will default to Static even if Embedded was set in ModifySourceArchive function +# https://github.com/mcneel/rhinocommon/blob/master/dotnet/rhino/rhinosdkinstance.cs#L23 +if update_type == "Linked" and \ +block_definition.UpdateType == Rhino.DocObjects.InstanceDefinitionUpdateType.Static: + # you can't store user text on block definition + # and I'd rather not use the description field + # so store it on the first block instance user clicked and + # iterate through all of them (hoping that wasn't deleted) + # don't want to store it in document, because the block may be renamed/reinserted + # https://discourse.mcneel.com/t/can-you-add-user-text-to-block-definition/150530 + for block_instance_id in rs.BlockInstances(block_definition.Name): + block_instance_source_archive = rs.GetUserText(block_instance_id, key="SourceArchive") + if block_instance_source_archive: + model_base_point = Rhino.FileIO.File3dm.Read(block_instance_source_archive).Settings.ModelBasepoint + sc.doc.ModelBasepoint = model_base_point + rs.Command("-Cplane World Top") + rs.Command("-Insert File=No " + chr(34) + block_definition.Name + chr(34) + " Block " + str(model_base_point) + " 1 0") + rs.Command("SelLast") + rs.Command("Explode") + rs.Command("-Export " + chr(34) + block_instance_source_archive + chr(34)) + rs.Command("Delete") + sc.doc.ModelBasepoint = Rhino.Geometry.Point3d(0,0,0) + + sc.doc.InstanceDefinitions.ModifySourceArchive(block_definition.Index, + block_instance_source_archive, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + quiet=1) + + rs.SelectObject(block_id) + + # use the first one found - problably should + # add extra checks in case there are multiple paths + break \ No newline at end of file diff --git a/XrefRemoveDWG.py b/XrefRemoveDWG.py new file mode 100644 index 0000000..11cab77 --- /dev/null +++ b/XrefRemoveDWG.py @@ -0,0 +1,5 @@ +import scriptcontext as sc + +for i in sc.doc.InstanceDefinitions: + if i.SourceArchive and ".dwg" in i.SourceArchive: + sc.doc.InstanceDefinitions.Purge(i.Index) \ No newline at end of file diff --git a/XrefSel.py b/XrefSel.py new file mode 100644 index 0000000..0e6a69b --- /dev/null +++ b/XrefSel.py @@ -0,0 +1,21 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import itertools + +def XrefSel(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + + # rs.BlockContainerCount excludes nested blocks, but doesn't work + # in externally linked blocks - WARNING! ">" character can be used + # on filenames in Linux + xrefs = [i.Name for i in block_definitions_list + if i.SourceArchive and + rs.BlockContainerCount(i.Name) == 0 + and ">" not in i.Name] + + selected_xref = rs.ComboListBox(sorted(xrefs)) + xref_instances = rs.BlockInstances(selected_xref) + rs.SelectObjects(xref_instances) + +XrefSel() \ No newline at end of file diff --git a/XrefSelMultiple.py b/XrefSelMultiple.py new file mode 100644 index 0000000..8f35db7 --- /dev/null +++ b/XrefSelMultiple.py @@ -0,0 +1,23 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc +import itertools + +def XrefSel(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + + # rs.BlockContainerCount excludes nested blocks, but doesn't work + # in externally linked blocks - WARNING! ">" character can be used + # on filenames in Linux + xrefs = [i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False + and rs.BlockContainerCount(i.Name) == 0 + and ">" not in i.Name] + + selected_xrefs = rs.MultiListBox(sorted(xrefs)) + xref_instances = [rs.BlockInstances(selected_xref) for selected_xref in selected_xrefs] + # https://stackoverflow.com/a/953097 - unpacking lists in python + xref_instances_unpacked = list(itertools.chain(*xref_instances)) + rs.SelectObjects(xref_instances_unpacked) + +XrefSel() \ No newline at end of file diff --git a/XrefShow.py b/XrefShow.py new file mode 100644 index 0000000..779bfbd --- /dev/null +++ b/XrefShow.py @@ -0,0 +1,11 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +layer_names = rs.LayerNames() +xref_layers = [i.replace('xref-AR000::', '') for i in layer_names if "xref-AR000::" in i] +selected_layers = rs.MultiListBox(xref_layers) + +for layer in selected_layers: + layer_index = sc.doc.Layers.FindByFullPath('xref-AR000::' + layer, notFoundReturnValue=False) + layer_object = sc.doc.Layers.FindIndex(layer_index) + layer_object.IsVisible = True \ No newline at end of file diff --git a/XrefShowAll.py b/XrefShowAll.py new file mode 100644 index 0000000..d1aff4f --- /dev/null +++ b/XrefShowAll.py @@ -0,0 +1,13 @@ +#check if rewriting in RhinoCommon would be faster +#seems now that toggling layers' visibility is much faster + +import rhinoscriptsyntax as rs + +def XrefShowAll(): + all_layers = rs.LayerNames() + xref_layers = [layer.replace('xref-AR000::', '') for layer in all_layers + if "xref-AR000::" in layer] + for xref_layer in xref_layers: + rs.LayerVisible(xref_layer, visible=True) + +XrefShowAll() \ No newline at end of file diff --git a/XrefShowBlocks.py b/XrefShowBlocks.py new file mode 100644 index 0000000..0285484 --- /dev/null +++ b/XrefShowBlocks.py @@ -0,0 +1,16 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def XrefShowBlocks(): + block_definitions = sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True) + block_definitions_list = list(block_definitions) + linked_blocks=[i.Name for i in block_definitions_list + if rs.IsBlockEmbedded(i.Name)==False and + ">" not in i.Name] + selection_names = rs.MultiListBox(sorted(linked_blocks)) + selection_instances = list() + for selection_name in selection_names: + selection_instances.append(rs.BlockInstances(selection_name)) + rs.ShowObjects(selection_instances) + +XrefShowBlocks() \ No newline at end of file diff --git a/XrefShowLayersAndBlocks.py b/XrefShowLayersAndBlocks.py new file mode 100644 index 0000000..5368b17 --- /dev/null +++ b/XrefShowLayersAndBlocks.py @@ -0,0 +1,17 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +def GetXrefLayers(): + a=rs.LayerNames() + b=[i.replace('xref-AR000::', '') for i in a if "xref-AR000::" in i] + c=rs.MultiListBox(b) + return c + +def XrefShowLayersAndBlocks(): + layers = GetXrefLayers() + for layer in layers: + objects = sc.doc.Objects.FindByLayer(layer) + rs.LayerVisible(layer, visible=True) + rs.ShowObjects(objects) + +XrefShowLayersAndBlocks() \ No newline at end of file diff --git a/XrefToggleVisibility.py b/XrefToggleVisibility.py new file mode 100644 index 0000000..32ea21e --- /dev/null +++ b/XrefToggleVisibility.py @@ -0,0 +1,13 @@ +import rhinoscriptsyntax as rs +import scriptcontext as sc + +layer_names = rs.LayerNames() +xref_layers = [i.replace('xref-AR000::', '') for i in layer_names if "xref-AR000::" in i] +selected_layers = rs.MultiListBox(xref_layers) + +for layer_short_name in selected_layers: + layer_index = sc.doc.Layers.FindByFullPath('xref-AR000::' + layer_short_name, + notFoundReturnValue=False) + layer_object = sc.doc.Layers.FindIndex(layer_index) + # ^= XOR toggling value on and off + layer_object.IsVisible ^= True \ No newline at end of file diff --git a/_PrintAllAsSeparatePages.py b/_PrintAllAsSeparatePages.py new file mode 100644 index 0000000..44a4bbc --- /dev/null +++ b/_PrintAllAsSeparatePages.py @@ -0,0 +1,56 @@ +import Rhino +import scriptcontext as sc +import System.Drawing +import rhinoscriptsyntax as rs +import os + +folder = os.getcwd() +titleblock = dict() + +def createSinglePDF(view, titleblock): + pdf = Rhino.FileIO.FilePdf.Create() + dpi = 300 + settings = Rhino.Display.ViewCaptureSettings(view, dpi) + settings.OutputColor = Rhino.Display.ViewCaptureSettings.ColorMode.DisplayColor + settings.DefaultPrintWidthMillimeters = 0.18 + pdf.AddPage(settings) + filename = folder + os.path.sep + titleblock.get("project_number","0000") + "-" + \ + titleblock.get("originator", "00") + "-" + \ + titleblock.get("zone", "00") + "-" + \ + titleblock.get("level", "00") + "-" + \ + titleblock.get("drawing_type", "00") + "-" + \ + titleblock.get("role", "0") + "-" + \ + titleblock.get("drawing_number", "00000") + "_" + \ + titleblock.get("latest_revision", "00") + " " + \ + titleblock.get("drawing_title_1", "000000000") + " " + \ + titleblock.get("drawing_title_2", "") + " " + \ + titleblock.get("drawing_title_3", "") + ".pdf" + pdf.Write(filename) + +for view in sc.doc.Views.GetPageViews(): + for object in sc.doc.Objects.FindByLayer("titleblock index-AR002"): + if type(object) == Rhino.DocObjects.TextObject and \ + view.ActiveViewportID == object.Attributes.ViewportId: + if object.Name == "Project Number": + titleblock["project_number"] = object.DisplayText + if object.Name == "Originator": + titleblock["originator"] = object.DisplayText + if object.Name == "Zone": + titleblock["zone"] = object.DisplayText + if object.Name == "Level": + titleblock["level"] = object.DisplayText + if object.Name == "Drawing Type": + titleblock["drawing_type"] = object.DisplayText + if object.Name == "Role": + titleblock["role"] = object.DisplayText + if object.Name == "Drawing Number": + titleblock["drawing_number"] = object.DisplayText + if object.Name == "Latest Revision": + titleblock["latest_revision"] = object.DisplayText + if object.Name == "Drawing Title 1": + titleblock["drawing_title_1"] = object.DisplayText + if object.Name == "Drawing Title 2": + titleblock["drawing_title_2"] = object.DisplayText + if object.Name == "Drawing Title 3": + titleblock["drawing_title_3"] = object.DisplayText + createSinglePDF(view, titleblock) \ No newline at end of file diff --git a/_QuickInsertToAutoCAD.py b/_QuickInsertToAutoCAD.py new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/_QuickInsertToAutoCAD.py @@ -0,0 +1 @@ + diff --git a/_XrefFilePathSourceV7.py b/_XrefFilePathSourceV7.py new file mode 100644 index 0000000..dd94d3d --- /dev/null +++ b/_XrefFilePathSourceV7.py @@ -0,0 +1,15 @@ +import os +import rhinoscriptsyntax as rs +import scriptcontext as sc +import Rhino + +block_defs = list(sc.doc.InstanceDefinitions.GetList(ignoreDeleted=True)) + +for idx, block_def in enumerate(block_defs): + if rs.IsBlockEmbedded(block_def.Name) == False and ".3dm" in block_def.SourceArchive: + block_folder, block_file_name = os.path.split(block_def.SourceArchive) + new_block_path = block_folder + "\\RhinoV7\\" + block_file_name + sc.doc.InstanceDefinitions.ModifySourceArchive(block_def.Index, + new_block_path, + Rhino.DocObjects.InstanceDefinitionUpdateType.Linked, + 0) \ No newline at end of file diff --git a/cplane harvester.gh b/cplane harvester.gh new file mode 100644 index 0000000000000000000000000000000000000000..eee15713e353f4e1b28aaf1115127ca7c4dec3d6 GIT binary patch literal 9292 zcmV-SB(vM?S$8=fc%HpL!GRS`=j2S|qBkM$~~CtP|ianW84smVvGgMhd~A#PYc z1@=&VdtetE+Fi0H1Zi(@-35YW6Yd^Nz01>rBb>obSPl^SWR!{!q%{KSvWE*+L_8ub zurp-ui_zM}2@HdP?7;|E2oeQBh}zkc>j7e5@j~uliG8T|s0wg247GPO4kth&2SDQ8 zLkM=sBnDuF9RxR%9r$bm-tk-8+e9XCxbtr?%MxD!bl!IqIhJzZ7;-&p7Y*=rI2!f) zTnc3b9PM&oGKm}-We-REP9jx+JG+2k*Y{Ls(Sut7ID#~-wIC2D5HCm$iG*820T_|{ zAfi$PyFzV1dT1010wXnqSRtXPpUlHG>2rv?94|f5~B4HzH4R@weR*}twZ7XVIFCn8( zzZa<3rx3XUH%K4n7UT+W7zzx9?f5;#?rxL{Xe0{md>ILa+3g8~|0h>slLIMmi)twu zfOc45D<=pDP~Qa(1EPjT$p(soBXr=%pK*!xgCkf-u|pMxM1f(}5M?yfW>0Q0!mw}c z&q9?$`bSg(^s0*gMs6}KsI}woECK~?Ds41M2aEuSs2z21V$7mW)X+@7G_V1&XzdiGEld@uiqVpX*{FdZqdv!UnC3$!b$ zsGN-r|ISXLxOsbmf_9|)osZpkkL|rDpw6DgJNxajwe~c_zRy$QykkFhN6=W>j_9I* z?7RMao*{2&il#0E#=#u08R;NjT-V?iDd?}j|F4%Bt04shVONdU)B zf%>P3fqVzXa!GbWf?N9ahCM&3**r+41l;DY z>#&1thyH7!R=}W)e#2K;%)2Ky$mX>>eonyOonUO!7>56XT(M&Ih$giVW82RO1b;JO zM`D~p*h46HC8m{ga)P@VARrJqYikG+`Hvw;zvIN9D?qBjg`fK$Jh-?4E}c`j>cnAw{ik4@eFaJQXPHS0ckF z+3}M-B!j;dw=s);(x{Rla(gM?>PWf6K43bEy`6sLwIx2{uENq~t=ldZQCo7yjsI2G z@&la578t^SYq|W@wQhvsTx-`8e%ga{R}7NKzXDVYa9s8QwAW$%9U4b==7L=I!gV*R{1F7hF(sOGKB&qqLBU=(rN`&@ zfk3je@SuzC(*G?`c>E(2`+bGrKY@bj02H`X`bQ*~zp_*%YQbf1p6N3Zya6NKhXgTh z-2otW$^RA{0{;<*5QW`7WUo^{(1&m#%d_=Gnw2BW%TK;)>ekwCS$UwPg2VPVA!Pr6 zB-_pc5FB?X$PJ3J2cg{HAXl&x8iJ%#a(6)hfeI}6)m!5Lx&(GYLg;_7b+GT9{u;|C zGC-gqe>BHmGu5BOKj@gd^#86w@c+gjcr}0_t^=^Q0PiBXUFZq^4*IxfpNs=XS5+&X zl~xox4r}apB^@Akoc1G6zPr<(kmr{J+!t7ZZC*guxb_ePg98HN(i{rnj@mWCA7RY5 zs@7OL;-;9I@$zf2*jDTxL^*&W-kK1-_w$>`5CL}ixrXQxd+~&StIip|zm@J_kq7Ai zYM%ZMIF~yxP6275?Lga1pooVTr9g=*J{C}H!-)&7f5@^t8gOfDh{15N4F|5U0CKo* z0EaygNK~LUHjtk`w&4F!|7RjGU;Xg>Wm9s99}|p%_t$l@y<-k2kFRks_Wu&!f9)9l zwuSr`FwkoZTuHV?jyhSk zA|qgYW_a3kA4Ei07dZ%z!NIotznT92EARyVBRnDd;Mr@5{;r%*VdH$yo&Jamho?9L z3e&FOho13o<7x=nj|+DBL0t6z=X)Tm;&=a1@hAlv9qg}*NNj1?yOZMY;!Au0aT0k1 zpsGFIZwc+-BqD4U{+S9q#l4ACQ4rjn7hw}Mxq&@EgMp#Hv_C*S4p2TG!^69+qoqtu!GZ%-RYg$`*jO0& zyO9hl(?GR4PBf&RvOHcv%dttUM0RqT00hP1ls~}O&V}4X#TW@(R|2sEKm5x)keH8M zQ&p5Ra5tYxSTj6iSJ5zjF$Ossn`F!D)}j$velIqj{I*qx{nZh_8)RH|gI&-F lLXX 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 literal 0 HcmV?d00001 diff --git a/diff.gh b/diff.gh new file mode 100644 index 0000000000000000000000000000000000000000..b411287c45e929d68976548838ee2698ba4a2179 GIT binary patch literal 6295 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