Trouble Moving Dimension Grips

python
rhino5

#1

Background:
When a bunch of geometry that includes dimensions is mirrored, the “architectural tick” style arrows become mirrored as well. I’m writing a script to flip them back.

Problem:

import rhinoscriptsyntax as rs
import scriptcontext as sc

dimGuid = rs.GetObject("Select dimension", custom_filter=rs.IsDimension)
if dimGuid:
	dimObj = sc.doc.Objects.Find(dimGuid)
	rs.EnableObjectGrips(dimGuid, True)
	g = rs.ObjectGripLocations(dimGuid)
	rs.MirrorObject(dimGuid, g[2], g[3])
	rs.ObjectGripLocation(dimGuid, 0, g[0])
	rs.EnableObjectGrips(dimGuid, False)

When I run this code, the dimension does not update. Reading and printing the grip locations before and after shows that the call to rs.ObjectGripLocation at the end has no effect.

I’ve tried several different ways to change the grip locations and nothing has worked. I thought I’d start with this most basic way that I would expect to work and go from there.

(Rhino 5)

EDIT:
It appears to work for Radial Dimensions, but not for Linear Dimensions, Aligned Dimensions, or Angular Dimensions.


#2

@Measure, what SR of RH5 are you using ?

I see it update immediately but the dimension jumps to a different place. (SR12)

This bug has been fixed in RH6 btw.
_
c.


#3

Yes, the MirrorObject on line 9 works, but the ObjectGripLocation on the next line does not.

Sorry for the confusion.

Version 5 SR14 64-bit
(5.14.522.8390, 5/22/2017)


#4

@Measure, below seems to do it on already mirrored linear or aligned dimensions:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
import math

def DoSomething():
    
    msg = "Select mirrored linear or aligned dimension"
    dim_id = rs.GetObject(msg, rs.filter.annotation)
    if not dim_id: return
    
    dim_obj = rs.coercerhinoobject(dim_id, True, True)
    if not isinstance(dim_obj, Rhino.DocObjects.LinearDimensionObject): 
        return
    
    geo = dim_obj.Geometry
    point = (geo.Arrowhead1End + geo.Arrowhead2End) * 0.5
    plane = geo.Plane
    plane.Origin = geo.Plane.PointAt(point.X, point.Y)
    plane.Rotate(math.radians(90.0), plane.YAxis)
    xform = Rhino.Geometry.Transform.Mirror(plane)
    scriptcontext.doc.Objects.Transform(dim_obj, xform, True)
    scriptcontext.doc.Views.Redraw()
    
DoSomething()

I guess you can do the same for radial or angular dims if you build the plane origin and rotation axis from the grip locations…
_
c.


#5

Thanks for your help!

This still doesn’t do exactly what I need in the case of dimensions with different-length extension lines, but I found a workaround for that. Here it is for reference:

def MoveGrip(dimGuid, index, p2): # substitute for rs.ObjectGripLocation
	if rs.ObjectGripsOn(dimGuid) and index in range(rs.ObjectGripCount(dimGuid)):
		redraw = rs.EnableRedraw(False)
		selected = rs.SelectedObjects(include_grips=True)
		rs.UnselectAllObjects()
		g = rs.ObjectGripLocations(dimGuid)
		rs.SelectObjectGrip(dimGuid, index)
		p1 = g[index]
		rs.Command("_Move {},{},{} {},{},{}".format(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z), echo=False)
		rs.UnselectAllObjects()
		rs.SelectObjects(selected)
		rs.EnableRedraw(redraw)

Everything works now!