SOHANDLEBOXDRAGGER(3iv)
π SoHandleBoxDragger(3IV) π
okay bestie, gather round, because today we're talking about SoHandleBoxDragger(3IV) β yes the (3IV) is part of the name, it's giving library-section energy, we love that for her. This is the box you can scale, stretch and translate by dragging with the mouse. no cap. let's get into it π
π NAME π
SoHandleBoxDragger β a box you can scale, stretch and translate by dragging with the mouse. literally what it says on the tin, she's an icon, she's a legend, and she IS the moment π
𧬠INHERITS FROM π§¬
ok so this is her whole family tree, from the great-great-grandparents down to her:
SoBase > SoFieldContainer > SoNode > SoBaseKit > SoInteractionKit >
SoDragger > SoHandleBoxDragger
she inherited everything and honestly? good for her π
β¨ SYNOPSIS β¨
first things first, you gotta include her header, or she simply will not appear:
#include <Inventor/draggers/SoHandleBoxDragger.h>
π¦ Fields from class SoHandleBoxDragger
SoSFVec3f scaleFactor
SoSFVec3f translation
π¦ Fields from class SoDragger
SoSFBool isActive
π¦ Fields from class SoInteractionKit
SoSFEnum renderCaching
SoSFEnum boundingBoxCaching
SoSFEnum renderCulling
SoSFEnum pickCulling
π¦ Parts from class SoBaseKit
(SoNodeKitListPart) callbackList
π¦ Methods from class SoHandleBoxDragger
SoHandleBoxDragger()
static const SoNodekitCatalog *
getClassNodekitCatalog() const
static SoType getClassTypeId()
π¦ Methods from class SoDragger
void addStartCallback(SoDraggerCB *f, void *userData =
NULL)
void removeStartCallback(SoDraggerCB *f, void *userData =
NULL)
void addMotionCallback(SoDraggerCB *f, void *userData =
NULL)
void removeMotionCallback(SoDraggerCB *f, void *userData =
NULL)
void addFinishCallback(SoDraggerCB *f, void *userData =
NULL)
void removeFinishCallback(SoDraggerCB *f, void *userData =
NULL)
void addValueChangedCallback(SoDraggerCB *f, void *userData
= NULL)
void removeValueChangedCallback(SoDraggerCB *f, void
*userData = NULL)
SbBool enableValueChangedCallbacks()
void setMinGesture(int pixels)
int getMinGesture() const
static void setMinScale(float newMinScale)
static float getMinScale()
π¦ Methods from class SoInteractionKit
virtual SbBool setPartAsPath(const SbName &partName, SoPath
*surrogatePath )
π¦ Methods from class SoBaseKit
virtual const SoNodekitCatalog *
getNodekitCatalog() const
virtual SoNode * getPart(const SbName &partName, SbBool
makeIfNeeded)
SbString getPartString(const SoBase *part)
virtual SoNodeKitPath * createPathToPart(const SbName &partName, SbBool
makeIfNeeded, const SoPath *pathToExtend =
NULL)
virtual SbBool setPart(const SbName &partName, SoNode *newPart)
SbBool set(char *partName, char *parameters)
SbBool set(char *nameValuePairs)
static SbBool isSearchingChildren()
static void setSearchingChildren(SbBool newVal)
π¦ Methods from class SoNode
void setOverride(SbBool state)
SbBool isOverride() const
SoNode * copy(SbBool copyConnections = FALSE) const
virtual SbBool affectsState() const
static SoNode * getByName(const SbName &name)
static int getByName(const SbName &name, SoNodeList &list)
π¦ Methods from class SoFieldContainer
void setToDefaults()
SbBool hasDefaultValues() const
SbBool fieldsAreEqual(const SoFieldContainer *fc) const
void copyFieldValues(const SoFieldContainer *fc, SbBool
copyConnections = FALSE)
void get(SbString &fieldDataString)
virtual int getFields(SoFieldList &resultList) const
virtual SoField * getField(const SbName &fieldName) const
SbBool getFieldName(const SoField *field, SbName &fieldName)
const
SbBool isNotifyEnabled() const
SbBool enableNotify(SbBool flag)
π¦ Methods from class SoBase
void ref()
void unref() const
void unrefNoDelete() const
void touch()
virtual SoType getTypeId() const
SbBool isOfType(SoType type) const
virtual void setName(const SbName &name)
virtual SbName getName() const
π¦ Macros from class SoBaseKit
SO_GET_PART(kit, partName, partClass)
SO_CHECK_PART(kit, partName, partClass)
πΈ DESCRIPTION πΈ
ok so picture this: SoHandleBoxDragger is a dragger shaped like a wireframe box, and it's got little corner cubes mounted on each corner. click and drag any of those cubes and the box scales uniformly. slay β¨
then there's six other center cubes β these ones are centered on the sides of the box β and white lines connect them to the center of the dragger. drag one of those center cubes along its line and you stretch the box in that direction. and if you drag a face of the box? that translates the dragger within that plane. three whole moods, one dragger π
while you're dragging a face of the box, purple feedback arrows show up displaying the possible directions of motion. hit the <Shift> key and the motion gets constrained to one of the two major directions in the plane β and the constraint direction is chosen based on the next user gesture, so it's lowkey reading your mind. hit the <Control> key instead and the dragger translates perpendicular to that plane. the translation field gets modified as the face is dragged.
by default, dragging any of the small cubes scales about the center of the object. but press the <Control> key and everything changes, bestie: a corner cube will scale about its opposite corner, and a center cube will scale about the center of its opposite face. dragging one of the small cubes will usually change both the scaleFactor and translation fields β and there's a reason for that! it's because any scale about a point other than the origin has a translation element. math said periodt. π
as with all draggers, if you change the fields, the dragger will move to match the new settings. she's responsive like that.
π¨ REMEMBER: This is not an SoTransform! π¨
if you wanna move other objects with this dragger, you've got two options, and you gotta pick one:
- [a] Use an
SoHandleBoxManip, which is subclassed fromSoTransform. it creates one of these draggers and uses it as the interface to change its fields. (see theSoHandleBoxManipreference page). - [b] Use field-to-field connections to connect the fields of this dragger to those of any
SoTransformationnode.
you can change the parts in any instance of this dragger using setPart(). the default part geometries are defined as resources for this SoHandleBoxDragger class, and they're detailed in the Dragger Resources section of the online reference page for this class. wanna make your program use different default resources for the parts? easy:
- copy the file
/usr/share/data/draggerDefaults/handleBoxDragger.ivinto your own directory - edit the file
- set the environment variable
SO_DRAGGER_DIRto be a path to that directory
and boom, custom resources, you're basically a wizard now π§
π FIELDS π
SoSFVec3f scaleFactorβ scale of the dragger.SoSFVec3f translationβ position of the dragger.
π«Ά METHODS π«Ά
SoHandleBoxDragger()β constructor. she's born β¨static const SoNodekitCatalog * getClassNodekitCatalog() constβ returns anSoNodekitCatalogfor this class.static SoType getClassTypeId()β returns the type identifier for this class.
and bestie, we're not done yet β there's more where this came from π
β¨ CATALOG PARTS β¨
okay bestie, this is the part where we meet the whole cast π every single part in the catalog, what type it is, and whether it's NULL by default. Spoiler: literally all of them are "yes" on that last one, no cap. The default type column is just -- for everybody, so don't come for me about it π«Ά
Here's the full roster, no skipping, every last one of them:
callbackListβ Part Type:NodeKitListPart, Default Type:--, NULL by default: yessurroundScaleβ Part Type:SurroundScale, Default Type:--, NULL by default: yestranslator1β Part Type:Separator, Default Type:--, NULL by default: yestranslator1Activeβ Part Type:Separator, Default Type:--, NULL by default: yestranslator2β Part Type:Separator, Default Type:--, NULL by default: yestranslator2Activeβ Part Type:Separator, Default Type:--, NULL by default: yestranslator3β Part Type:Separator, Default Type:--, NULL by default: yestranslator3Activeβ Part Type:Separator, Default Type:--, NULL by default: yestranslator4β Part Type:Separator, Default Type:--, NULL by default: yestranslator4Activeβ Part Type:Separator, Default Type:--, NULL by default: yestranslator5β Part Type:Separator, Default Type:--, NULL by default: yestranslator5Activeβ Part Type:Separator, Default Type:--, NULL by default: yestranslator6β Part Type:Separator, Default Type:--, NULL by default: yestranslator6Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder1β Part Type:Separator, Default Type:--, NULL by default: yesextruder1Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder2β Part Type:Separator, Default Type:--, NULL by default: yesextruder2Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder3β Part Type:Separator, Default Type:--, NULL by default: yesextruder3Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder4β Part Type:Separator, Default Type:--, NULL by default: yesextruder4Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder5β Part Type:Separator, Default Type:--, NULL by default: yesextruder5Activeβ Part Type:Separator, Default Type:--, NULL by default: yesextruder6β Part Type:Separator, Default Type:--, NULL by default: yesextruder6Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform1β Part Type:Separator, Default Type:--, NULL by default: yesuniform1Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform2β Part Type:Separator, Default Type:--, NULL by default: yesuniform2Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform3β Part Type:Separator, Default Type:--, NULL by default: yesuniform3Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform4β Part Type:Separator, Default Type:--, NULL by default: yesuniform4Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform5β Part Type:Separator, Default Type:--, NULL by default: yesuniform5Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform6β Part Type:Separator, Default Type:--, NULL by default: yesuniform6Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform7β Part Type:Separator, Default Type:--, NULL by default: yesuniform7Activeβ Part Type:Separator, Default Type:--, NULL by default: yesuniform8β Part Type:Separator, Default Type:--, NULL by default: yesuniform8Activeβ Part Type:Separator, Default Type:--, NULL by default: yesarrow1β Part Type:Separator, Default Type:--, NULL by default: yesarrow2β Part Type:Separator, Default Type:--, NULL by default: yesarrow3β Part Type:Separator, Default Type:--, NULL by default: yesarrow4β Part Type:Separator, Default Type:--, NULL by default: yesarrow5β Part Type:Separator, Default Type:--, NULL by default: yesarrow6β Part Type:Separator, Default Type:--, NULL by default: yes
π Extra info for the list parts from that table up there
so most of those parts are just plain Separator vibes, but a couple of them are list parts and they got β¨rangeβ¨ β here's the tea:
callbackList- Container Type:
Separator - Permissible Types:
Callback,EventCallback
- Container Type:
that's literally it for the extras, bestie. one list part, two permissible types. she's small but she's mighty π
π DRAGGER RESOURCES π
alright, now the main character section π€ this is every resource you can poke at, what part it maps to, what it looks like, and what happens when you pick it. eyes on the prize, we're going through all of them.
π Translator handles
handleBoxTranslator1- Part:
translator1 - Appearance: White Line-Style Square
- Description: Top face of handleBox. Picking this initiates scaling in x-z plane.
- Part:
handleBoxTranslator2- Part:
translator2 - Appearance: White Line-Style Square
- Description: Bottom face of handleBox. Picking this initiates scaling in x-z plane.
- Part:
handleBoxTranslator3- Part:
translator3 - Appearance: White Line-Style Square
- Description: Left face of handleBox. Picking this initiates scaling in y-z plane.
- Part:
handleBoxTranslator4- Part:
translator4 - Appearance: White Line-Style Square
- Description: Right face of handleBox. Picking this initiates scaling in y-z plane.
- Part:
handleBoxTranslator5- Part:
translator5 - Appearance: White Line-Style Square
- Description: Front face of handleBox. Picking this initiates scaling in x-y plane.
- Part:
handleBoxTranslator6- Part:
translator6 - Appearance: White Line-Style Square
- Description: Back face of handleBox. Picking this initiates scaling in x-y plane.
- Part:
π Translator handles but they're active (the glow-up versions)
handleBoxTranslator1Active- Part:
translator1Active - Appearance: Yellow version of
handleBoxTranslator1 - Description: Replaces
handleBoxTranslator1during dragging.
- Part:
handleBoxTranslator2Active- Part:
translator2Active - Appearance: Yellow version of
handleBoxTranslator2 - Description: Replaces
handleBoxTranslator2during dragging.
- Part:
handleBoxTranslator3Active- Part:
translator3Active - Appearance: Yellow version of
handleBoxTranslator3 - Description: Replaces
handleBoxTranslator3during dragging.
- Part:
handleBoxTranslator4Active- Part:
translator4Active - Appearance: Yellow version of
handleBoxTranslator4 - Description: Replaces
handleBoxTranslator4during dragging.
- Part:
handleBoxTranslator5Active- Part:
translator5Active - Appearance: Yellow version of
handleBoxTranslator5 - Description: Replaces
handleBoxTranslator5during dragging.
- Part:
handleBoxTranslator6Active- Part:
translator6Active - Appearance: Yellow version of
handleBoxTranslator6 - Description: Replaces
handleBoxTranslator6during dragging.
- Part:
π¦ Extruder cubes (1-D scaling girlies)
handleBoxExtruder1- Part:
extruder1 - Appearance: Small white cube at
(0,1.25,0)with line to origin - Description: Selecting this part initiates 1-D scaling along Y axis.
- Part:
handleBoxExtruder2- Part:
extruder2 - Appearance: Small white cube at
(0,-1.25,0)with line to origin - Description: Selecting this part initiates 1-D scaling along Y axis.
- Part:
handleBoxExtruder3- Part:
extruder3 - Appearance: Small white cube at
(-1.25,0,0)with line to origin - Description: Selecting this part initiates 1-D scaling along X axis.
- Part:
handleBoxExtruder4- Part:
extruder4 - Appearance: Small white cube at
(1.25,0,0)with line to origin - Description: Selecting this part initiates 1-D scaling along X axis.
- Part:
handleBoxExtruder5- Part:
extruder5 - Appearance: Small white cube at
(0,0,1.25)with line to origin - Description: Selecting this part initiates 1-D scaling along Z axis.
- Part:
handleBoxExtruder6- Part:
extruder6 - Appearance: Small white cube at
(0,0,-1.25)with line to origin - Description: Selecting this part initiates 1-D scaling along Z axis.
- Part:
π Extruder cubes but active (again, the yellow era)
handleBoxExtruder1Active- Part:
extruder1Active - Appearance: Yellow version of
handleBoxExtruder1 - Description: Replaces
handleBoxExtruder1during dragging.
- Part:
handleBoxExtruder2Active- Part:
extruder2Active - Appearance: Yellow version of
handleBoxExtruder1 - Description: Replaces
handleBoxExtruder1during dragging.
- Part:
handleBoxExtruder3Active- Part:
extruder3Active - Appearance: Yellow version of
handleBoxExtruder3 - Description: Replaces
handleBoxExtruder3during dragging.
- Part:
handleBoxExtruder4Active- Part:
extruder4Active - Appearance: Yellow version of
handleBoxExtruder4 - Description: Replaces
handleBoxExtruder4during dragging.
- Part:
π yes bestie,handleBoxExtruder2Activereally does say "Yellow version ofhandleBoxExtruder1" and "ReplaceshandleBoxExtruder1" β that's exactly what the page says, and I am not the one editing the source, iykyk. reporting it as-is, no cap.
handleBoxExtruder5Activeβ Part:extruder5Activeβ¨ Appearance: yellow version ofhandleBoxExtruder5π Description: replaceshandleBoxExtruder5during dragging.handleBoxExtruder6Activeβ Part:extruder6Activeβ¨ Appearance: yellow version ofhandleBoxExtruder6π Description: replaceshandleBoxExtruder6during dragging.
okay now the uniform cubes, the little white corner gremlins that do the scaling π
handleBoxUniform1β Part:uniform1β¨ Appearance: small white cube in the(+x+y+z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform2β Part:uniform2β¨ Appearance: small white cube in the(+x+y-z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform3β Part:uniform3β¨ Appearance: small white cube in the(+x-y+z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform4β Part:uniform4β¨ Appearance: small white cube in the(+x-y-z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform5β Part:uniform5β¨ Appearance: small white cube in the(-x+y+z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform6β Part:uniform6β¨ Appearance: small white cube in the(-x+y-z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform7β Part:uniform7β¨ Appearance: small white cube in the(-x-y+z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform8β Part:uniform8β¨ Appearance: small white cube in the(-x-y-z)corner ofhandleBoxπ Description: picking this initiates uniform scaling.handleBoxUniform1Activeβ Part:uniform1Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging. (yes bestie, that's exactly how the page says it β I'm reading it to you character for character π )handleBoxUniform2Activeβ Part:uniform2Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform3Activeβ Part:uniform3Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform4Activeβ Part:uniform4Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform5Activeβ Part:uniform5Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform6Activeβ Part:uniform6Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform7Activeβ Part:uniform7Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.handleBoxUniform8Activeβ Part:uniform8Activeβ¨ Appearance: yellow version ofhandleBoxUniform1ActiveπΌ Description: replaceshandleBoxUniform1Activeduring dragging.
and the arrows, the purple directional besties πΉ
handleBoxArrow1β Part:arrow1π Appearance: purple arrow, pointing up β¬οΈ Description: displayed when translating if Y direction is permitted.handleBoxArrow2β Part:arrow2π Appearance: purple arrow, pointing down β¬οΈ Description: displayed when translating if Y direction is permitted.handleBoxArrow3β Part:arrow3π Appearance: purple arrow, pointing left β¬ οΈ Description: displayed when translating if X direction is permitted.handleBoxArrow4β Part:arrow4π Appearance: purple arrow, pointing right β‘οΈ Description: displayed when translating if X direction is permitted.handleBoxArrow5β Part:arrow5π Appearance: purple arrow, pointing forward π₯ Description: displayed when translating if Z direction is permitted.handleBoxArrow6β Part:arrow6π Appearance: purple arrow, pointing backward π₯ Description: displayed when translating if Z direction is permitted.
π¦ FILE FORMAT/DEFAULTS π¦
here's the whole default vibe, verbatim, don't @ me:
HandleBoxDragger {
renderCaching AUTO
boundingBoxCaching AUTO
renderCulling AUTO
pickCulling AUTO
isActive FALSE
translation 0 0 0
scaleFactor 1 1 1
callbackList NULL
surroundScale NULL
translator1 <handleBoxTranslator1 resource>
translator1Active <handleBoxTranslator1Active resource>
translator2 <handleBoxTranslator2 resource>
translator2Active <handleBoxTranslator2Active resource>
translator3 <handleBoxTranslator3 resource>
translator3Active <handleBoxTranslator3Active resource>
translator4 <handleBoxTranslator4 resource>
translator4Active <handleBoxTranslator4Active resource>
translator5 <handleBoxTranslator5 resource>
translator5Active <handleBoxTranslator5Active resource>
translator6 <handleBoxTranslator6 resource>
translator6Active <handleBoxTranslator6Active resource>
extruder1 <handleBoxExtruder1 resource>
extruder1Active <handleBoxExtruder1Active resource>
extruder2 <handleBoxExtruder2 resource>
extruder2Active <handleBoxExtruder2Active resource>
extruder3 <handleBoxExtruder3 resource>
extruder3Active <handleBoxExtruder3Active resource>
extruder4 <handleBoxExtruder4 resource>
extruder4Active <handleBoxExtruder4Active resource>
extruder5 <handleBoxExtruder5 resource>
extruder5Active <handleBoxExtruder5Active resource>
extruder6 <handleBoxExtruder6 resource>
extruder6Active <handleBoxExtruder6Active resource>
uniform1 <handleBoxUniform1 resource>
uniform1Active <handleBoxUniform1Active resource>
uniform2 <handleBoxUniform2 resource>
uniform2Active <handleBoxUniform2Active resource>
uniform3 <handleBoxUniform3 resource>
uniform3Active <handleBoxUniform3Active resource>
uniform4 <handleBoxUniform4 resource>
uniform4Active <handleBoxUniform4Active resource>
uniform5 <handleBoxUniform5 resource>
uniform5Active <handleBoxUniform5Active resource>
uniform6 <handleBoxUniform6 resource>
uniform6Active <handleBoxUniform6Active resource>
uniform7 <handleBoxUniform7 resource>
uniform7Active <handleBoxUniform7Active resource>
uniform8 <handleBoxUniform8 resource>
uniform8Active <handleBoxUniform8Active resource>
arrow1 <handleBoxArrow1 resource>
arrow2 <handleBoxArrow2 resource>
arrow3 <handleBoxArrow3 resource>
arrow4 <handleBoxArrow4 resource>
arrow5 <handleBoxArrow5 resource>
arrow6 <handleBoxArrow6 resource>
}
β οΈ NOTE β οΈ
okay so this is the tea and it's kind of iconic actually:
Unlike most multi-function draggers,SoHandleBoxDraggeris not a compound dragger made up of other draggers that perform its smaller tasks. This is not because it was inappropriate, but because was written before implementation of the methods that synchronize multiple child draggers. The youngerSoTransformBoxDraggerhas similarities to the handle box dragger, but the transform box dragger is a compound dragger.
so basically: it's a lone wolf πΊ, not a friend group. not because the friend group was a bad idea β it just got written before the friend-group-syncing code existed. the newer SoTransformBoxDragger is similar but does do the compound thing. growth π
π SEE ALSO π
go read these next, bestie, they're all part of the same family π«Ά
SoInteractionKitSoDraggerSoCenterballDraggerSoDirectionalLightDraggerSoDragPointDraggerSoJackDraggerSoPointLightDraggerSoRotateCylindricalDraggerSoRotateDiscDraggerSoRotateSphericalDraggerSoScale1DraggerSoScale2DraggerSoScale2UniformDraggerSoScaleUniformDraggerSoSpotLightDraggerSoTabBoxDraggerSoTabPlaneDraggerSoTrackballDraggerSoTransformBoxDraggerSoTransformerDraggerSoTranslate1DraggerSoTranslate2Dragger
and that's the whole page, no cap π footer says SoHandleBoxDragger(3IV)() β so it's the 3IV version, and the date slot is just... vibes and empty parens π which honestly is its own kind of iconic. go forth and drag, you gorgeous genius β¨π¦π
π¦ where this page comes from
- debian bookworm: inventor-doc 2.1.5-10+dfsg-2 Β· LGPL-2.0-or-later
- debian trixie: inventor-doc 2.1.6+ds-2 Β· LGPL-2.0-or-later
- ubuntu jammy: inventor-doc 2.1.5-10-24
- ubuntu noble: inventor-doc 2.1.5-10+dfsg-2.1build2 Β· LGPL-2.0-or-later
- ubuntu questing: inventor-doc 2.1.6+ds-2
- ubuntu resolute: inventor-doc 2.1.6.1+ds-1 Β· LGPL-2.0-or-later
- ubuntu stonking: inventor-doc 2.1.6.1+ds-1 Β· LGPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms