[vtk-developers] Improvements to the transform pipeline (3 vtkTransform derived classes).

David Gobbi david.gobbi at gmail.com
Tue Jun 5 12:05:53 EDT 2018


Hi Patrick,

That's not possible since vtkTransform is in "Common" while vtkProp3D is in
"Rendering".  It's expected that "Rendering" should depend on "Common", but
not vice-versa.

An adapter is better.  It allows a Prop3D to be used anywhere in VTK that a
transform can be used, without requiring modifications to any other VTK
classes.

 - David


On Tue, Jun 5, 2018 at 9:52 AM, Patrick Bergeron <pbergeron at spiria.com>
wrote:

> And, here’s another thing that could be done to vtkTransform to eliminate
> my actor-to-transform adapter class. It would be super easy to do, and be
> backwards compatible.
>
>
>
> Currently: vtkTransform::SetInput(vtkAbstractTransform*)
>
> Suggestion: vtkTransform::SetInput(vtkObject*)
>
>
>
> vtkTransform::InternalUpdate()
>
>>
>>
>>
> If (this->Input)
>
> {
>
>      vtkAbstractTransform *transform = vtkAbstractTransform::
> SafeDownCast(this->Input);
>
>      vtkProp3D *prop3D = vtkProp3D::SafeDownCast(this->Input);
>
>
>
>      If (transform != nullptr)
>
>                 this->Matrix->DeepCopy(transform->GetMatrix());
>
>      else if (prop3D != nullptr)
>
>               this->Matrix->DeepCopy(prop3D->GetMatrix());
>
>      else
>
>               vtkWarningMacro(“InternalUpdate: Bad object type passed as
> input”);
>
>
>
>>
>>
> }
>
>
>
> This way, actors can directly be an input into the transformation
> pipeline, the same way as is a normal transform.
>
>
>
>
>
>
>
>
>
>
>
> *From: *vtk-developers <vtk-developers-bounces at public.kitware.com> on
> behalf of David Gobbi <david.gobbi at gmail.com>
> *Date: *Tuesday, June 5, 2018 at 11:13 AM
> *To: *Andras Lasso <lasso at queensu.ca>
> *Cc: *"vtk-developers at public.kitware.com" <vtk-developers at public.
> kitware.com>
> *Subject: *Re: [vtk-developers] Improvements to the transform pipeline (3
> vtkTransform derived classes).
>
>
>
> Hi Andras, Patrick,
>
>
>
> I'd just like to add that vtkTransform itself supports dynamic
> concatenation, it isn't necessary to use vtkGeneralTransform unless you
> want to concatenate nonlinear transformations.
>
>
>
> Here's an example (unfortunately it was auto-converted to Python from Tcl
> so it's poorly formatted):
>
> https://gitlab.kitware.com/vtk/vtk/blob/master/Rendering/
> Core/Testing/Python/TransformConcatenation.py
>
>
>
>  - David
>
>
>
>
>
>
>
> On Tue, Jun 5, 2018 at 9:06 AM, Andras Lasso <lasso at queensu.ca> wrote:
>
> Hi Patrick,
>
>
>
> I think these problems are already solved, since you can dynamically
> concatenate any number of transforms in any combinations (including
> inverting them) using vtkGeneralTransform.
>
>
>
> Regarding your solution proposed for “problem” 3: Ability to temporarily
> bypass a transform without changing the pipeline would be a feature that I
> would find useful. Some warping transforms already have scale parameter for
> enabling/disabling (or slightly emphasizing or de-emphasizing) a
> transformation, which comes very handy for visualizing the effect of the
> transformation. This feature could be generalized and moved to
> vtkAbstractTransform class.
>
>
>
> Andras
>
>
>
> ---------- Forwarded message ----------
> From: *Patrick Bergeron* <pbergeron at spiria.com>
> Date: Tue, Jun 5, 2018 at 10:33 AM
> Subject: [vtk-developers] Improvements to the transform pipeline (3
> vtkTransform derived classes).
> To: "vtk-developers at public.kitware.com" <vtk-developers at public.kitware.com
> >
>
> Hi everyone.
>
>
>
> I've been using VTK for a bit now, and I've made a few improvements I'd
> like to contribute to the community.
>
>
>
> Before I do, however, I'd like to know if there is interest in me doing
> so before I go through the hassles of submission.
>
>
>
>
>
> GENERAL PROBLEM STATEMENT  (MOTIVATION)
>
> ---------------------------------------------------------------
>
>
>
> I have a list of objects that I'd like to transform using a single widget.
> Widgets take a single vtkProp3D as target. For (multiple) reasons beyond
> the scope of this discussion, I couldn't use vtkAssembly to target my
> multiple actors. Plus, I wanted each actor to transform according to their
> local reference frame, not the reference frame of the vtkAssembly.
>
>
>
>
>
> PROBLEM (1/3)
>
> ---------------------
>
> vtkTransform can take as input another vtkTransform, to which it
> concatenates its own SRT values,  its output being it the concatenation of
> the input transform and itself.
>
>
>
> This is useful and allows for multiple scenarios, including this common
> pattern of parent-child hierarchical chain of transforms, as is shown in
> this Robot-Arm example.
>
> https://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/TransformPipeline
> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.vtk.org%2FWiki%2FVTK%2FExamples%2FCxx%2FPolyData%2FTransformPipeline&data=02%7C01%7Classo%40queensu.ca%7C6b89e9286a8c496b460808d5caf28d0e%7Cd61ecb3b38b142d582c4efb2838b925c%7C1%7C0%7C636638065458569187&sdata=pXnPwQTqvWrH1L2NOrQR33gpasKrz2H3CEtfwRXSMqg%3D&reserved=0>
>
>
>
> In the example above, 3 transforms are chained together, and
>
> xform1 --to--> xform2's input ,   xform2's output -- to --> xform3's input.
>
>
>
> xform1 is set as the user transform of the root actor
>
> xform2 is set as the user transform of the mid actor
>
> xform3 is set as the user transform of the leaf actor
>
>
>
> In other words, the *parent's transform* is inherited, and each actor's
> *local transformation* is controlled by calling the normal functions, such
> as TranslateX, RotateY, etc, and when concatenated provides the
> actor's *global transform*
>
>
>
> That's all fine, as long as you want to, or can, control each of the local
> transform directly.  But what if you'd like to also control the *local
> transform* via another transformation pipeline?  The vtkTransform's input
> is already taken by the parent transform, were would I plug the local
> transform's input?
>
>
>
>
>
> SOLUTION (1/3) --  Introducing vtkDualInputTransform
>
> ------------------------------------------------------------------------
>
>
>
> As its name implies, vtkDualInput transform adds a second input (Input2)
> to the standard vtkTransform.
>
>
>
> Whereas the vtkTransform's output was :   GetMatrix() = [INPUT][MYSELF],
>
> Then vtkDualInputTransform's putput is : GetMatrix() =
> [INPUT][INPUT2] [MYSELF]
>
> (with adaptations wrt Pre-Post multiply flag).
>
>
>
> In vtkDualInputTransform, both Input1 and Input2 can be muted, so that
> they are skipped, just as if there was no input connected.  (It's like
> closing a gate)
>
>
>
>
>
> ADVANTAGES
>
> -------------------
>
>
>
> With the vtkDualInputTransform, you can create complex chains of
> transforms that allows for direct control of different parts of the
> transform multiple actors from a single source.
>
>
>
> In my case, Input1 is the parent transform, Input2 is the local transform,
> and  I leave the internals alone (set to Identity).
>
> The result is thus GetMatrix() = [INPUT][INPUT2][IDENTITY]
> = [INPUT][INPUT2]
>
>
>
> Using this pattern, I have 100 actors driven by different pipelines, yet I
> can affect all of them at once by changing a common transformation pipeline
> that is plugged into the second input.
>
>
>
>
>
>
>
>
>
>
>
>
>
> PROBLEM (2/3)
>
> ---------------------
>
>
>
> With the vtkDualInputTransform in place, which I could plug into an
> Actor's UserTransform, I could now effect the global transform using 2
> transformation pipelines (its parent tranform, and its local transform).
>
>
>
> But, what if I wanted to transform my actors by setting affecting
> their local transforms using another actor as the driver?
>
> (why? because a widget targets a prop/actor, and I want the changes to the
> targetted actor's transformation to propagate down to a transformation
> pipeline to affect other actors)
>
>
>
> In other words, I want:
>
>
>
> widget -> actorA's transform -> input of vtkTransform --> input
> of vtkTransform --> input of vtkTansform --> input of actorB, actorC,
> actorD (etc)'s UserTransform.
>
>
>
> While we can do actorA's GetMatrix() (which is the concat of its input and
> own pos/ori/scale/origin/etc), there is unfortunately, there is no way to
> do actor->GetTransform() (since it might get pushed/popped from the stack,
> it might not always be valid, might disappear etc).   So how do I drive a
> transform pipeline from an actor?
>
>
>
>
>
> SOLUTION (2/3) --  Introducing vtkProp3DTransformAdapter
>
> ------------------------------------------------------------
> -------------------
>
>
>
> This is another derivative of vtkTransform. It has a SetProp3D method,
> which serves the same purpose as the vtkTransform's input.
>
> (in fact, vtkProp3DTransformAdapter's input is not used, and a warning is
> issued if it is)
>
>
>
> In vtkProp3DTransformAdapter, in the InternalUpdate method, instead of
> calling Input->GetMatrix(), we simply call prop3D->GetMatrix(), which
> ensures is always valid.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> PROBLEM (3/3)
>
> --------------------
>
>
>
> Finally, there's a catch: I want to affect multiple actors's global
> transform but control the local transform, but there's a catch when doing
> [INPUT][INPUT2].
>
>
>
> Indeed, that concatenation is (roughly) the equivalent of:
>
>
>
> Result = [IN_scl] x [IN_ori] x [IN_trs] x [IN2_scl] x [IN2_ori] x
> [IN2_trs].
>
>
>
> In other words, by the time we multiply IN2, IN's translation is already
> considered, so scale and rotation of the 2nd input will have their
> transformation center set to IN's translation, which a problem.
>
>
>
> What I want instead is consider the concatenation of the scale,
> orientation, and transformation :
>
>
>
> Result = [IN_scl] x [IN2_scl]   x   [IN_ori] x [IN2_ori]   x   [IN_trs] x
> [IN2_trs].
>
>
>
>
>
>
>
> SOLUTION (3/3) -- Introducing vtkMutableTransform
>
> ---------------------------------------------------------------------
>
>
>
> Unfortunately, I did not find a proper name for this one, as "mutable" can
> imply "changeable".   But I meant it to mean that you could "mute" portions
> of the transform.
>
>
>
> The goal of this derived class is that you feed it a transform, and out
> comes the same transform without the muted portions. For example, the
> transform's output is the same as the input, with scaling, orientation, or
> translation stripped out.
>
>
>
>
>
>
>
>
>
>
>
> CONCLUSION:
>
> --------------------
>
>
>
> Using the proper combination of the 3 vtkTransform derivatives described
> above, and chained together in the proper order, you can make a
> transformation graph that is fully automated and controllable from any
> point or any source in the transform pipeline.
>
>
>
>
>
>
>
> Let me know if there is interest in me submitting these 3 classes.
>
>
>
> Regards
>
> Patrick Bergeron
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtk-developers/attachments/20180605/60be1395/attachment-0001.html>


More information about the vtk-developers mailing list