Fix GearConnector circular recompute dependency

- Call purgeTouched() on slave gear after Placement modifications
  - Mark computed properties as Output (flag 8) instead of read-only (flag 1)
    to prevent triggering recomputes when set during execute()

  Resolves infinite recompute loop and "still touched after recompute" warning.
This commit is contained in:
Chris Bruner
2025-11-03 17:25:40 -05:00
committed by lorenz
parent 33cbe81938
commit 649c7cfb7c
3 changed files with 20 additions and 13 deletions

View File

@@ -141,6 +141,7 @@ class GearConnector(object):
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
fp.slave_gear.purgeTouched()
if isinstance(fp.master_gear.Proxy, InternalInvoluteGear) and isinstance(
fp.slave_gear.Proxy, InvoluteGear
@@ -174,6 +175,7 @@ class GearConnector(object):
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
fp.slave_gear.purgeTouched()
if (
isinstance(fp.master_gear.Proxy, InvoluteGear)
@@ -198,6 +200,7 @@ class GearConnector(object):
mat3 = rot * mat2 * mat1 * mat0
mat3.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat3
fp.slave_gear.purgeTouched()
if isinstance(fp.master_gear.Proxy, CycloidGear) and isinstance(
fp.slave_gear.Proxy, CycloidGear
@@ -221,6 +224,7 @@ class GearConnector(object):
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
fp.slave_gear.purgeTouched()
def execute(self, fp):
self.onChanged(fp, None)

View File

@@ -131,7 +131,7 @@ class InternalInvoluteGear(BaseGear):
"pitch_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The pitch diameter."),
1,
8,
)
obj.pitch_diameter = pitch_diameter
obj.removeProperty("dw")
@@ -146,7 +146,7 @@ class InternalInvoluteGear(BaseGear):
"addendum_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The addendum diameter."),
1,
8,
)
obj.addendum_diameter = addendum_diameter
obj.removeProperty("da")
@@ -159,7 +159,7 @@ class InternalInvoluteGear(BaseGear):
"root_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The root diameter."),
1,
8,
)
obj.root_diameter = root_diameter
obj.removeProperty("df")
@@ -200,6 +200,7 @@ class InternalInvoluteGear(BaseGear):
"pitch_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The pitch diameter."),
8,
)
obj.addProperty(
"App::PropertyAngle",
@@ -209,6 +210,7 @@ class InternalInvoluteGear(BaseGear):
"App::Property",
"The angle by which this gear can turn without moving the mating gear.",
),
8,
)
obj.setExpression(
"angular_backlash", "backlash / pitch_diameter * 360° / pi"
@@ -221,14 +223,14 @@ class InternalInvoluteGear(BaseGear):
"transverse_pitch",
"computed",
QT_TRANSLATE_NOOP("App::Property", "transverse_pitch"),
1,
8,
)
obj.addProperty(
"App::PropertyLength",
"outside_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "Outside diameter"),
1,
8,
)
def add_fillet_properties(self, obj):

View File

@@ -95,7 +95,7 @@ class InvoluteGear(BaseGear):
"pitch_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The pitch diameter."),
1,
8,
)
obj.pitch_diameter = pitch_diameter
obj.removeProperty("dw")
@@ -110,7 +110,7 @@ class InvoluteGear(BaseGear):
"addendum_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The addendum diameter."),
1,
8,
)
obj.addendum_diameter = addendum_diameter
obj.removeProperty("da")
@@ -123,7 +123,7 @@ class InvoluteGear(BaseGear):
"root_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The root diameter."),
1,
8,
)
obj.root_diameter = root_diameter
obj.removeProperty("df")
@@ -265,14 +265,14 @@ class InvoluteGear(BaseGear):
"addendum_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The outside diameter"),
1,
8,
)
obj.addProperty(
"App::PropertyLength",
"root_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The root diameter"),
1,
8,
)
self.add_traverse_module_property(obj)
obj.addProperty(
@@ -280,7 +280,7 @@ class InvoluteGear(BaseGear):
"pitch_diameter",
"computed",
QT_TRANSLATE_NOOP("App::Property", "The pitch diameter."),
1,
8,
)
obj.addProperty(
"App::PropertyAngle",
@@ -290,6 +290,7 @@ class InvoluteGear(BaseGear):
"App::Property",
"The angle by which this gear can turn without moving the mating gear.",
),
8,
)
obj.setExpression(
"angular_backlash", "backlash / pitch_diameter * 360° / pi"
@@ -302,7 +303,7 @@ class InvoluteGear(BaseGear):
"transverse_pitch",
"computed",
QT_TRANSLATE_NOOP("App::Property", "transverse_pitch"),
1,
8,
)
def add_tolerance_properties(self, obj):
@@ -356,7 +357,7 @@ class InvoluteGear(BaseGear):
"traverse_module",
"computed",
QT_TRANSLATE_NOOP("App::Property", "traverse module of the generated gear"),
1,
8,
)
def compute_traverse_properties(self, obj):