Skip to content

Commit

Permalink
Merge pull request #1 from Ultimaker/CURA-10916_infill_generate_plugin
Browse files Browse the repository at this point in the history
CURA-10619 infill generate plugin
  • Loading branch information
casperlamboo authored Aug 7, 2023
2 parents 0832523 + 3840656 commit 357f7c3
Show file tree
Hide file tree
Showing 32 changed files with 1,630 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ForEachMacros:
IncludeBlocks: Regroup
IncludeCategories:
- Priority: 2
Regex: ^<(scripta|spdlog|range|fmt|Arcus|agrpc|grpc|boost|polyclipping|docopt|google|grp.*)/
Regex: ^<(scripta|spdlog|range|fmt|Arcus|agrpc|grpc|boost|polyclipping|docopt|google|grp.*|ctre)/
- Priority: 3
Regex: ^(<|"(gtest|gmock|isl|json)/)
- Priority: 1
Expand Down
133 changes: 133 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
### C++ template
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

### CMake template
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

### CLion+all template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

.idea/
conan.lock
conanbuildinfo.txt
conaninfo.txt
graph_info.json
build/
CMakeUserPresets.json
29 changes: 29 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.25)
project(curaengine_plugin_infill_generate)

find_package(Protobuf REQUIRED)
find_package(spdlog REQUIRED)
find_package(docopt REQUIRED)
find_package(asio-grpc REQUIRED)
find_package(range-v3 REQUIRED)
find_package(clipper REQUIRED)
find_package(ctre REQUIRED)
find_package(neargye-semver REQUIRED)

asio_grpc_protobuf_generate(PROTOS "${GRPC_PROTOS}"
IMPORT_DIRS ${GRPC_IMPORT_DIRS}
OUT_VAR "ASIO_GRPC_PLUGIN_PROTO_SOURCES"
OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated"
GENERATE_GRPC GENERATE_MOCK_CODE)

add_executable(curaengine_plugin_infill_generate ${PROTO_SRCS} ${ASIO_GRPC_PLUGIN_PROTO_SOURCES} src/main.cpp)

target_include_directories(curaengine_plugin_infill_generate
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
${CMAKE_CURRENT_BINARY_DIR}/generated
)

target_link_libraries(curaengine_plugin_infill_generate PUBLIC clipper::clipper ctre::ctre asio-grpc::asio-grpc protobuf::libprotobuf boost::boost spdlog::spdlog docopt_s range-v3::range-v3 neargye-semver::neargye-semver)

74 changes: 74 additions & 0 deletions CuraEngineInfillGenerate/CuraEngineInfillGenerate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import os
import platform
import stat
import sys
from pathlib import Path

from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.i18n import i18nCatalog
from cura.BackendPlugin import BackendPlugin

catalog = i18nCatalog("cura")


class CuraEngineInfillGenerate(BackendPlugin):
def __init__(self):
super().__init__()
self.definition_file_paths = [Path(__file__).parent.joinpath("infill_settings.def.json").as_posix()]
self._tiles_path = Path(__file__).parent.joinpath("tiles")
if not self.isDebug():
if not self.binaryPath().exists():
Logger.error(f"Could not find CuraEngineInfillGenerate binary at {self.binaryPath().as_posix()}")
if platform.system() != "Windows" and self.binaryPath().exists():
st = os.stat(self.binaryPath())
os.chmod(self.binaryPath(), st.st_mode | stat.S_IEXEC)

self._plugin_command = [self.binaryPath().as_posix(), "--tiles_path", self._tiles_path.as_posix()]

self._supported_slots = [200] # ModifyPostprocess SlotID
ContainerRegistry.getInstance().containerLoadComplete.connect(self._on_container_load_complete)

def _on_container_load_complete(self, container_id) -> None:
if not ContainerRegistry.getInstance().isLoaded(container_id):
# skip containers that could not be loaded, or subsequent findContainers() will cause an infinite loop
return
try:
container = ContainerRegistry.getInstance().findContainers(id=container_id)[0]
except IndexError:
# the container no longer exists
return
if not isinstance(container, DefinitionContainer):
# skip containers that are not definitions
return
if container.getMetaDataEntry("type") == "extruder":
# skip extruder definitions
return

for infill_patterns in ("infill_pattern"): # , "support_pattern", "support_interface_pattern", "support_roof_pattern", "support_bottom_pattern", "roofing_pattern", "top_bottom_pattern", "ironing_pattern"):
for definition in container.findDefinitions(key=infill_patterns):
for pattern in self.getTilePatterns():
definition.extend_category(pattern[0], pattern[1], plugin_id=self.getPluginId(), plugin_version=self.getVersion())

def getTilePatterns(self):
tile_paths = self._tiles_path.glob("*.wkt")
return [(p.name.replace(" ", "_").replace(".wkt", ""), " ".join([w.capitalize() for w in p.name.replace("_", " ").replace(".wkt", "").split(" ")])) for p in tile_paths]

def getPort(self):
return super().getPort() if not self.isDebug() else int(os.environ["CURAENGINE_INFILL_GENERATE_PORT"])

def isDebug(self):
return not hasattr(sys, "frozen") and os.environ.get("CURAENGINE_INFILL_GENERATE_PORT", None) is not None

def start(self):
if not self.isDebug():
super().start()

def binaryPath(self) -> Path:
ext = ".exe" if platform.system() == "Windows" else ""

platform = platform.machine()
if platform == "AMD64":
platform = "x86_64"
return Path(__file__).parent.joinpath(platform, platform.system(), f"curaengine_plugin_infill_generate{ext}").resolve()
25 changes: 25 additions & 0 deletions CuraEngineInfillGenerate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2023 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.

import platform

if platform.machine() in ["AMD64", "x86_64"]:
from . import CuraEngineInfillGenerate

from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")

def getMetaData():
return {}

def register(app):
return { "backend_plugin": CuraEngineInfillGenerate.CuraEngineInfillGenerate() }
else:
from UM.Logger import Logger
Logger.error("CuraEngineInfillGenerate plugin is only supported on x86_64 systems")

def getMetaData():
return {}

def register(app):
return {}
40 changes: 40 additions & 0 deletions CuraEngineInfillGenerate/infill_settings.def.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"infill": {
"children": {
"tile_shape": {
"label": "Tile Shape",
"description": "The shape of the tiles.",
"type": "enum",
"options": {
"square": "Square",
"hexagon": "Hexagon"
},
"default_value": "hexagon",
"value": "hexagon",
"enabled": "infill_pattern.startswith(\"PLUGIN\")",
"limit_to_extruder": "infill_extruder_nr",
"settable_per_mesh": true
},
"tile_size": {
"label": "Tile Size",
"description": "Size of the tiles.",
"unit": "mm",
"type": "float",
"minimum_value": "0.5",
"maximum_value_warning": "250",
"maximum_value": "500",
"default_value": 2,
"settable_per_mesh": "True",
"enabled": "infill_pattern.startswith(\"PLUGIN\")"
},
"absolute_tiles": {
"label": "Absolute Tile Coordinates",
"description": "Fix the tile coordinates to the absolute position of the buildplate.",
"type": "bool",
"default_value": true,
"settable_per_mesh": "True",
"enabled": "infill_pattern.startswith(\"PLUGIN\")"
}
}
}
}
8 changes: 8 additions & 0 deletions CuraEngineInfillGenerate/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "CuraEngine Infill Generate plugin",
"author": "UltiMaker",
"description": "A test plugin for CuraEngine",
"api": 8,
"version": "0.1.0",
"i18n-catalog": "cura"
}
3 changes: 3 additions & 0 deletions CuraEngineInfillGenerate/tiles/cont_honeycomb.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POLYGON ((866 2000, 1732 1500, 1732 500, 866 0, 0 500, 0 1500))
LINESTRING (866 0, 166 404, 166 1595, 866 2000)
LINESTRING (1830 404, 1834 404, 1834 1595)
3 changes: 3 additions & 0 deletions CuraEngineInfillGenerate/tiles/cura.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POLYGON (( 709 952, 0 952, 0 243, 243 0, 952 0, 952 709 ))
POLYGON (( 709 952, 105 846, 666 846, 846 666, 846 105, 285 105, 105 285, 105 846 ))
POLYGON (( 635 687, 476 687, 394 671, 326 625, 281 558, 264 476, 281 394, 326 326, 394 281, 476 264, 635 264, 635 370, 476 370, 401 401, 370 476, 401 550, 476 582, 635 582, 635 687 ))
5 changes: 5 additions & 0 deletions CuraEngineInfillGenerate/tiles/fill.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
POLYGON(( 866 2000, 1732 1500, 1732 500, 866 0, 0 500, 0 1500 ))
POLYGON(( 866 1800, 1558 1400, 1558 600, 866 200, 173 600, 173 1400 ))
POLYGON(( 866 1600, 1385 1300, 1385 700, 866 400, 346 700, 346 1300 ))
POLYGON(( 866 1400, 1212 1200, 1212 800, 866 600, 519 800, 519 1200 ))
POLYGON(( 866 1200, 1039 1100, 1039 900, 866 800, 692 900, 692 1100 ))
2 changes: 2 additions & 0 deletions CuraEngineInfillGenerate/tiles/honeycomb.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
POLYGON ((866 2000, 1732 1500, 1732 500, 866 0, 0 500, 0 1500))
LINESTRING (866 0, 0 500, 0 1500, 866 2000)
2 changes: 2 additions & 0 deletions CuraEngineInfillGenerate/tiles/lightning.wkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
POLYGON (( 866 2000, 1732 1500, 1732 500, 866 0, 0 500, 0 1500 ))
POLYGON (( 1299 250, 466 900, 766 1000, 433 1750, 1166 900, 966 800 ))
1 change: 1 addition & 0 deletions CuraEngineInfillGenerate/x86_64/Darwin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curaengine_plugin_infill_generate
1 change: 1 addition & 0 deletions CuraEngineInfillGenerate/x86_64/Linux/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curaengine_plugin_infill_generate
1 change: 1 addition & 0 deletions CuraEngineInfillGenerate/x86_64/Windows/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curaengine_plugin_infill_generate.exe
Loading

0 comments on commit 357f7c3

Please sign in to comment.