Merge pull request #2 from jdegenstein/dev

Dev to Main
This commit is contained in:
jdegenstein
2022-10-21 03:13:34 +00:00
committed by GitHub
7 changed files with 67 additions and 194 deletions

View File

@@ -36,13 +36,13 @@ jobs:
pip install git+https://github.com/meadiode/cq_gears.git@main pip install git+https://github.com/meadiode/cq_gears.git@main
pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache" pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache"
pip install git+https://github.com/gumyr/build123d.git#egg=build123d pip install git+https://github.com/gumyr/build123d.git#egg=build123d
pip install git+https://github.com/JustinSDK/cqMore
- name: Run build - name: Run build
shell: bash --login {0} shell: bash --login {0}
run: | run: |
micromamba info micromamba info
pyinstaller pyinstaller.spec ${{ github.event.inputs.type }} pyinstaller pyinstaller.spec ${{ github.event.inputs.type }}
cp /home/runner/work/jmwright-CQ-Editor/jmwright-CQ-Editor/pyinstaller/CQ-editor.sh /home/runner/work/jmwright-CQ-Editor/jmwright-CQ-Editor/dist/ cp /home/runner/work/jmwright-CQ-Editor/jmwright-CQ-Editor/pyinstaller/CQ-editor.sh /home/runner/work/jmwright-CQ-Editor/jmwright-CQ-Editor/dist/
rm /home/runner/work/jmwright-CQ-Editor/jmwright-CQ-Editor/dist/CQ-editor/libstdc++.so.6
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: CQ-editor-Linux-x86_64 name: CQ-editor-Linux-x86_64
@@ -73,6 +73,7 @@ jobs:
pip install git+https://github.com/meadiode/cq_gears.git@main pip install git+https://github.com/meadiode/cq_gears.git@main
pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache" pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache"
pip install git+https://github.com/gumyr/build123d.git#egg=build123d pip install git+https://github.com/gumyr/build123d.git#egg=build123d
pip install git+https://github.com/JustinSDK/cqMore
- name: Run build - name: Run build
shell: bash --login {0} shell: bash --login {0}
run: | run: |
@@ -107,6 +108,7 @@ jobs:
pip install git+https://github.com/meadiode/cq_gears.git@main pip install git+https://github.com/meadiode/cq_gears.git@main
pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache" pip install -e "git+https://github.com/CadQuery/cadquery-plugins.git#egg=cq_cache&subdirectory=plugins/cq_cache"
pip install git+https://github.com/gumyr/build123d.git#egg=build123d pip install git+https://github.com/gumyr/build123d.git#egg=build123d
pip install git+https://github.com/JustinSDK/cqMore
- name: Run build - name: Run build
shell: powershell shell: powershell
run: | run: |

View File

@@ -7,7 +7,7 @@ from types import SimpleNamespace
from OCP.XCAFPrs import XCAFPrs_AISObject from OCP.XCAFPrs import XCAFPrs_AISObject
from OCP.TopoDS import TopoDS_Shape from OCP.TopoDS import TopoDS_Shape
from OCP.AIS import AIS_InteractiveObject, AIS_Shape, AIS_ColoredShape from OCP.AIS import AIS_InteractiveObject, AIS_Shape
from OCP.Quantity import \ from OCP.Quantity import \
Quantity_TOC_RGB as TOC_RGB, Quantity_Color Quantity_TOC_RGB as TOC_RGB, Quantity_Color
@@ -33,6 +33,10 @@ def to_compound(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.
vals.append(cq.Shape.cast(obj)) vals.append(cq.Shape.cast(obj))
elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape): elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape):
vals.extend(cq.Shape.cast(o) for o in obj) vals.extend(cq.Shape.cast(o) for o in obj)
elif hasattr(obj, "wrapped") and isinstance(obj.wrapped, TopoDS_Shape):
vals.append(cq.Shape.cast(obj.wrapped))
elif hasattr(obj, "_obj") and hasattr(obj._obj, "wrapped") and isinstance(obj._obj.wrapped, TopoDS_Shape):
vals.append(cq.Shape.cast(obj._obj.wrapped))
elif isinstance(obj, cq.Sketch): elif isinstance(obj, cq.Sketch):
if obj._faces: if obj._faces:
vals.append(obj._faces) vals.append(obj._faces)
@@ -62,7 +66,7 @@ def make_AIS(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Sha
ais = obj ais = obj
else: else:
shape = to_compound(obj) shape = to_compound(obj)
ais = AIS_ColoredShape(shape.wrapped) ais = AIS_Shape(shape.wrapped)
if 'alpha' in options: if 'alpha' in options:
ais.SetTransparency(options['alpha']) ais.SetTransparency(options['alpha'])
@@ -105,13 +109,23 @@ def to_occ_color(color) -> Quantity_Color:
color.blueF(), color.blueF(),
TOC_RGB) TOC_RGB)
def get_occ_color(ais : AIS_ColoredShape) -> QColor: def get_occ_color(obj : Union[AIS_InteractiveObject, Quantity_Color]) -> QColor:
if isinstance(obj, AIS_InteractiveObject):
color = Quantity_Color() color = Quantity_Color()
ais.Color(color) obj.Color(color)
else:
color = obj
return QColor.fromRgbF(color.Red(), color.Green(), color.Blue()) return QColor.fromRgbF(color.Red(), color.Green(), color.Blue())
def set_color(ais : AIS_Shape, color : Quantity_Color) -> AIS_Shape:
drawer = ais.Attributes()
drawer.ShadingAspect().SetColor(color)
return ais
def reload_cq(): def reload_cq():
# NB: order of reloads is important # NB: order of reloads is important

View File

@@ -1,149 +0,0 @@
import cadquery as cq
from cadquery.occ_impl.assembly import toCAF
from typing import List, Union
from imp import reload
from types import SimpleNamespace
from OCP.XCAFPrs import XCAFPrs_AISObject
from OCP.TopoDS import TopoDS_Shape
from OCP.AIS import AIS_InteractiveObject, AIS_Shape, AIS_ColoredShape
from OCP.Quantity import \
Quantity_TOC_RGB as TOC_RGB, Quantity_Color
from PyQt5.QtGui import QColor
def find_cq_objects(results : dict):
return {k:SimpleNamespace(shape=v,options={}) for k,v in results.items() if isinstance(v,cq.Workplane)}
def to_compound(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Sketch]):
vals = []
if isinstance(obj,cq.Workplane):
vals.extend(obj.vals())
elif isinstance(obj,cq.Shape):
vals.append(obj)
elif isinstance(obj,list) and isinstance(obj[0],cq.Workplane):
for o in obj: vals.extend(o.vals())
elif isinstance(obj,list) and isinstance(obj[0],cq.Shape):
vals.extend(obj)
elif isinstance(obj, TopoDS_Shape):
vals.append(cq.Shape.cast(obj))
elif isinstance(obj,list) and isinstance(obj[0],TopoDS_Shape):
vals.extend(cq.Shape.cast(o) for o in obj)
elif isinstance(obj, cq.Sketch):
if obj._faces:
vals.append(obj._faces)
else:
vals.extend(obj._edges)
else:
raise ValueError(f'Invalid type {type(obj)}')
return cq.Compound.makeCompound(vals)
def to_workplane(obj : cq.Shape):
rv = cq.Workplane('XY')
rv.objects = [obj,]
return rv
def make_AIS(obj : Union[cq.Workplane, List[cq.Workplane], cq.Shape, List[cq.Shape], cq.Assembly, AIS_InteractiveObject],
options={}):
shape = None
if isinstance(obj, cq.Assembly):
label, shape = toCAF(obj)
ais = XCAFPrs_AISObject(label)
elif isinstance(obj, AIS_InteractiveObject):
ais = obj
else:
shape = to_compound(obj)
ais = AIS_ColoredShape(shape.wrapped)
if 'alpha' in options:
ais.SetTransparency(options['alpha'])
if 'color' in options:
ais.SetColor(to_occ_color(options['color']))
if 'rgba' in options:
r,g,b,a = options['rgba']
ais.SetColor(to_occ_color((r,g,b)))
ais.SetTransparency(a)
return ais,shape
def export(obj : Union[cq.Workplane, List[cq.Workplane]], type : str,
file, precision=1e-1):
comp = to_compound(obj)
if type == 'stl':
comp.exportStl(file, tolerance=precision)
elif type == 'step':
comp.exportStep(file)
elif type == 'brep':
comp.exportBrep(file)
def to_occ_color(color) -> Quantity_Color:
if not isinstance(color, QColor):
if isinstance(color, tuple):
if isinstance(color[0], int):
color = QColor(*color)
elif isinstance(color[0], float):
color = QColor.fromRgbF(*color)
else:
raise ValueError('Unknown color format')
else:
color = QColor(color)
return Quantity_Color(color.redF(),
color.greenF(),
color.blueF(),
TOC_RGB)
def get_occ_color(ais : AIS_ColoredShape) -> QColor:
color = Quantity_Color()
ais.Color(color)
return QColor.fromRgbF(color.Red(), color.Green(), color.Blue())
def reload_cq():
# NB: order of reloads is important
reload(cq.types)
reload(cq.occ_impl.geom)
reload(cq.occ_impl.shapes)
reload(cq.occ_impl.shapes)
reload(cq.occ_impl.importers.dxf)
reload(cq.occ_impl.importers)
reload(cq.occ_impl.solver)
reload(cq.occ_impl.assembly)
reload(cq.occ_impl.sketch_solver)
reload(cq.hull)
reload(cq.selectors)
reload(cq.sketch)
reload(cq.occ_impl.exporters.svg)
reload(cq.cq)
reload(cq.occ_impl.exporters.utils)
reload(cq.occ_impl.exporters.dxf)
reload(cq.occ_impl.exporters.amf)
reload(cq.occ_impl.exporters.json)
#reload(cq.occ_impl.exporters.assembly)
reload(cq.occ_impl.exporters)
reload(cq.assembly)
reload(cq)
def is_obj_empty(obj : Union[cq.Workplane,cq.Shape]) -> bool:
rv = False
if isinstance(obj, cq.Workplane):
rv = True if isinstance(obj.val(), cq.Vector) else False
return rv

View File

@@ -9,7 +9,8 @@ from OCP.gp import gp_Dir, gp_Pnt, gp_Ax1
from ..mixins import ComponentMixin from ..mixins import ComponentMixin
from ..icons import icon from ..icons import icon
from ..cq_utils import make_AIS, export, to_occ_color, is_obj_empty, get_occ_color from ..cq_utils import make_AIS, export, to_occ_color, is_obj_empty, get_occ_color, set_color
from .viewer import DEFAULT_FACE_COLOR
from ..utils import splitter, layout, get_save_filename from ..utils import splitter, layout, get_save_filename
class TopTreeItem(QTreeWidgetItem): class TopTreeItem(QTreeWidgetItem):
@@ -49,14 +50,19 @@ class ObjectTreeItem(QTreeWidgetItem):
self.properties['Name'] = name self.properties['Name'] = name
self.properties['Alpha'] = ais.Transparency() self.properties['Alpha'] = ais.Transparency()
self.properties['Color'] = get_occ_color(ais) if ais else color self.properties['Color'] = get_occ_color(ais) if ais and ais.HasColor() else get_occ_color(DEFAULT_FACE_COLOR)
self.properties.sigTreeStateChanged.connect(self.propertiesChanged) self.properties.sigTreeStateChanged.connect(self.propertiesChanged)
def propertiesChanged(self,*args): def propertiesChanged(self, properties, changed):
changed_prop = changed[0][0]
self.setData(0,0,self.properties['Name']) self.setData(0,0,self.properties['Name'])
self.ais.SetTransparency(self.properties['Alpha']) self.ais.SetTransparency(self.properties['Alpha'])
self.ais.SetColor(to_occ_color(self.properties['Color']))
if changed_prop.name() == 'Color':
set_color(self.ais, to_occ_color(self.properties['Color']))
self.ais.Redisplay() self.ais.Redisplay()
if self.properties['Visible']: if self.properties['Visible']:

View File

@@ -1,22 +1,16 @@
# -*- coding: utf-8 -*- from PyQt5.QtWidgets import QWidget, QDialog, QTreeWidgetItem, QApplication, QAction
from OCP.Graphic3d import Graphic3d_Camera, Graphic3d_StereoMode from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (QWidget, QPushButton, QDialog, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QFileDialog,
QHBoxLayout, QFrame, QLabel, QApplication,
QToolBar, QAction)
from PyQt5.QtCore import QSize, pyqtSlot, pyqtSignal, QMetaObject, Qt
from PyQt5.QtGui import QIcon from PyQt5.QtGui import QIcon
from OCP.AIS import AIS_Shaded,AIS_WireFrame, AIS_ColoredShape, \ from OCP.Graphic3d import Graphic3d_Camera, Graphic3d_StereoMode, Graphic3d_NOM_JADE,\
AIS_Axis, AIS_Line Graphic3d_MaterialAspect
from OCP.Aspect import Aspect_GDM_Lines, Aspect_GT_Rectangular, Aspect_GFM_VER from OCP.AIS import AIS_Shaded,AIS_WireFrame, AIS_ColoredShape, AIS_Axis
from OCP.Quantity import Quantity_NOC_BLACK as BLACK, \ from OCP.Aspect import Aspect_GDM_Lines, Aspect_GT_Rectangular
from OCP.Quantity import Quantity_NOC_BLACK as BLACK, Quantity_NOC_GOLD as GOLD,\
Quantity_TOC_RGB as TOC_RGB, Quantity_Color Quantity_TOC_RGB as TOC_RGB, Quantity_Color
from OCP.Geom import Geom_CylindricalSurface, Geom_Plane, Geom_Circle,\ from OCP.Geom import Geom_Axis1Placement
Geom_TrimmedCurve, Geom_Axis1Placement, Geom_Axis2Placement, Geom_Line from OCP.gp import gp_Ax3, gp_Dir, gp_Pnt, gp_Ax1
from OCP.gp import gp_Trsf, gp_Vec, gp_Ax3, gp_Dir, gp_Pnt, gp_Ax1
from ..utils import layout, get_save_filename from ..utils import layout, get_save_filename
from ..mixins import ComponentMixin from ..mixins import ComponentMixin
@@ -27,7 +21,9 @@ from .occt_widget import OCCTWidget
from pyqtgraph.parametertree import Parameter from pyqtgraph.parametertree import Parameter
import qtawesome as qta import qtawesome as qta
DEFAULT_FACE_COLOR = Quantity_Color(GOLD)
DEFAULT_EDGE_COLOR = Quantity_Color(BLACK)
DEFAULT_EDGE_WIDTH = 2
class OCCViewer(QWidget,ComponentMixin): class OCCViewer(QWidget,ComponentMixin):
@@ -64,9 +60,23 @@ class OCCViewer(QWidget,ComponentMixin):
[self.canvas,], [self.canvas,],
top_widget=self, top_widget=self,
margin=0) margin=0)
self.setup_default_drawer() #misspelled in original
self.updatePreferences() self.updatePreferences()
def setup_default_drawer(self):
# set the default color and material
material = Graphic3d_MaterialAspect(Graphic3d_NOM_JADE)
shading_aspect = self.canvas.context.DefaultDrawer().ShadingAspect()
shading_aspect.SetMaterial(material)
shading_aspect.SetColor(DEFAULT_FACE_COLOR)
# face edge lw
line_aspect = self.canvas.context.DefaultDrawer().FaceBoundaryAspect()
line_aspect.SetWidth(DEFAULT_EDGE_WIDTH)
line_aspect.SetColor(DEFAULT_EDGE_COLOR)
def updatePreferences(self,*args): def updatePreferences(self,*args):
color1 = to_occ_color(self.preferences['Background color']) color1 = to_occ_color(self.preferences['Background color'])

View File

@@ -38,7 +38,7 @@ a = Analysis(['run.py'],
'pyqtgraph.imageview.ImageViewTemplate_pyqt5', 'xmlrpc', 'pyqtgraph.imageview.ImageViewTemplate_pyqt5', 'xmlrpc',
'zmq.backend', 'cq_warehouse', 'cq_warehouse.bearing', 'cq_warehouse.chain', 'zmq.backend', 'cq_warehouse', 'cq_warehouse.bearing', 'cq_warehouse.chain',
'cq_warehouse.drafting', 'cq_warehouse.extensions', 'cq_warehouse.fastener', 'cq_warehouse.drafting', 'cq_warehouse.extensions', 'cq_warehouse.fastener',
'cq_warehouse.sprocket', 'cq_warehouse.thread', 'cq_gears', 'cq_cache', 'build123d'] + hiddenimports1 + hiddenimports2, 'cq_warehouse.sprocket', 'cq_warehouse.thread', 'cq_gears', 'cq_cache', 'build123d', 'cqmore'] + hiddenimports1 + hiddenimports2,
hookspath=[], hookspath=[],
runtime_hooks=['pyinstaller/pyi_rth_occ.py', runtime_hooks=['pyinstaller/pyi_rth_occ.py',
'pyinstaller/pyi_rth_fontconfig.py'], 'pyinstaller/pyi_rth_fontconfig.py'],

View File

@@ -114,7 +114,7 @@ def get_rgba(ais):
alpha = ais.Transparency() alpha = ais.Transparency()
color = get_occ_color(ais) color = get_occ_color(ais)
return color.redF(),color.redF(),color.redF(),alpha return color.redF(), color.greenF(), color.blueF(), alpha
@pytest.fixture @pytest.fixture
def main(qtbot,mocker): def main(qtbot,mocker):
@@ -1017,14 +1017,13 @@ def test_render_colors(main_clean):
CQ = obj_tree.CQ CQ = obj_tree.CQ
# object 1 (defualt color) # object 1 (defualt color)
r,g,b,a = get_rgba(CQ.child(0).ais) assert not CQ.child(0).ais.HasColor()
assert( a == 0 )
assert( r != 1.0 )
# object 2 # object 2
r,g,b,a = get_rgba(CQ.child(1).ais) r,g,b,a = get_rgba(CQ.child(1).ais)
assert( a == 0.5 ) assert( a == 0.5 )
assert( r == 1.0 ) assert( r == 1.0 )
assert( g == 0.0 )
# object 3 # object 3
r,g,b,a = get_rgba(CQ.child(2).ais) r,g,b,a = get_rgba(CQ.child(2).ais)
@@ -1060,19 +1059,10 @@ def test_render_colors_console(main_clean):
console.execute_command(code_color) console.execute_command(code_color)
def get_rgba(ais):
alpha = ais.Transparency()
color = get_occ_color(ais)
return color.redF(),color.redF(),color.redF(),alpha
CQ = obj_tree.CQ CQ = obj_tree.CQ
# object 1 (defualt color) # object 1 (defualt color)
r,g,b,a = get_rgba(CQ.child(0).ais) assert not CQ.child(0).ais.HasColor()
assert( a == 0 )
assert( r != 1.0 )
# object 2 # object 2
r,g,b,a = get_rgba(CQ.child(1).ais) r,g,b,a = get_rgba(CQ.child(1).ais)