CRhinoPageView & CRhinoDetailViewObject



I would like to annotate some objects on a layout. The objects are 3D and I want the annotations (some text blocks, for example) to be on the layout (2D).

But I can’t find the function to convert a 3D point (W coordinates) into a 2D point (paper coordinates).
Does this exist ?


P.S.: My question is about C++ SDK.

Annotation on a layout
(Dale Fugier) #2

Hi Jean,

There is no such thing as “paper coordinates”. You draw in world coordinates when in a layout, just like you would if you were in a normal viewport.

(Steve Baer) #3

There is a GetPageXforms function on the CRhinoDetailViewObject if you are trying to transform between spaces


I attach an example with a box and 2 text blocks. The red one has been drawn in 3D (not what I’m looking for). The green one has been drawn in 2D (this is what I need).

What I’m trying to do is to put an annotation like the green one on a corner of the displayed box. That for I need to map between world coordinates and 2D coordinates (at least, that’s what I think but I may be wrong).


Thanks Steve.

I’ll give a try (although I was looking for something in Rhino 4 sdk).

(Steve Baer) #6

In Rhino 4 get the CRhinoViewport from the detail object and call GetXform


Thanks again Steve.

It looks like I’m not far from the goal but I miss a kind of scale factor.

I get the Xform:

ON_Xform world2camera;
detailViewObj->Viewport().m_v.m_vp.GetXform (
ON::world_cs, ON::camera_cs, world2camera);

then activate page view’s main viewport

  RhinoApp().SetActiveViewport (pageView->MainViewport().ViewportId());

then compute projectedPoint:

ON_3dPoint projectedPoint = world2camera * myWorldPoint;

then add a text block by running _Text command:

   myStream << L"-_Text " << projectedPoint.x
                          << L"," << projectedPoint.y
                          << L"," << projectedPoint.z
         << L" Height=5 " << "myText";

I’ve run a test with a selection of several objects. And the resulting text blocks almost well positioned: there is just a scale factor (see attached snapshot).

Any clue about which scale I should use ?

(Steve Baer) #8

I would get a world->screen transform from the detail viewport and a screen->world transform for the page viewport. Combining these will transform a point from detail space to page space.


I got it.

Thanks very much, Steve !


Hi @stevebaer, @dale,

i’ve used above way to transform objects (dimensions and curves) from model space to page space but have a problem with deviation. My detail viewport has the same size as the layout page, scaling is 1:1, however, i get deviations up to 0.25 mm which also changes dimension text from eg. 10.0 to 9.76.

Is there an alternate way to make this transform using Rhino 5 ?

Edit: i’ll attach 1 example page and script. Please run the script, pick the detail on Page 1, then a point is created. If you zoom in, the deviation from the origin point in modelspace is 0.25 (measured in page units).

Example.3dm (75.4 KB) (856 Bytes)


(Dale Fugier) #11

Hi @clement,

Does the ChangeSpace command provide the accuracy you need?

– Dale


Hi @Dale,

yes this looks promising and much more accurate than my script example. I’ve found how to use it in V5 by scripting the command. How would i do this with code so i can avoid selecting an object instead ? (I’ve seen your example here but have no idea how to convert it in python) In Rhino Common for V5 i only found the PageViewSpaceChange Event but no method to actually perform the change.

btw. for the simple case i demonstrated above i’ve been able to transform using a simple translation matrix (since the detail only shows a top view). But i’d like to apply the same what _ChangeSpace does using other views in my details too.


(Dale Fugier) #13

Hi @clement,

I think scripting the ChangeSpace command is your best option in Rhino 5.

Rhino 6 has has new DetailViewObject.WorldToPageTransform and DetailViewObject.PageToWorldTransform properties which provide the necessary transforms.

If you want to run your code through RhinoScript, you can use XformWorldToLayout andXFormLayoutToWorld```.

– Dale