def initializeDrawable(self): # Measure Line 1 self.guide_geo1 = hou.Geometry() line_verb = hou.sopNodeTypeCategory().nodeVerb("line") line_verb.setParms({ "origin": self.startpos, "dir": hou.Vector3(0, 1, 0), "dist": 1 }) line_verb.execute(self.guide_geo1, []) self.drawable1 = hou.SimpleDrawable(self.scene_viewer, self.guide_geo1, "guide_1") self.drawable1.enable(True) self.drawable1.show(True) # Measure Line 2 self.guide_geo2 = hou.Geometry() line_verb = hou.sopNodeTypeCategory().nodeVerb("line") line_verb.setParms({ "origin": self.startpos, "dir": hou.Vector3(0, 1, 0), "dist": 1 }) line_verb.execute(self.guide_geo2, []) self.drawable2 = hou.SimpleDrawable(self.scene_viewer, self.guide_geo2, "guide_2") self.drawable2.enable(True) self.drawable2.show(True)
def correct_normal(self, p, p_1, p_2, points_neighbors): n = int((math.ceil(len(points_neighbors) / float(10)))) e_dir = [np.zeros(3), np.zeros(3)] e_len = [0, 0] p_currs = [p_1, p_2] for direction in range(2): p_prev = p p_curr = p_currs[direction] for _ in range(n): e_curr = p_curr.position() - p.position() e_dir[direction] += e_curr e_len[direction] += e_curr.length() p_a, p_b = points_neighbors[p_curr] p_next = p_b if p_a == p_prev else p_a p_prev = p_curr p_curr = p_next e_dir1 = hou.Vector3(e_dir[0] / e_len[0]) e_dir2 = hou.Vector3(e_dir[1] / e_len[1]) normal_i = hou.Vector3(p.attribValue("N")) # NOTE: Paper says e1 x e2 / ||e1 x e2||, but e2 x e1 / ||e2 x e1|| makes sense normal_e = e_dir2.cross(e_dir1).normalized() normal_c = (alpha * normal_i + beta * normal_e).normalized() return normal_c
def getHandlePosition(self, index): ### Return the Position Offset vector at an index in the Handles List currentPos = hou.Vector3() if index > 0: currentPos = hou.Vector3(self.node.parmTuple("posOffset_%s" % (index)).eval()) return currentPos
def intersectOriginPlane(origin, direction): ### Intersect a flat plane to calculate a flat position offset vector planePos = hou.hmath.intersectPlane(hou.Vector3(0, 0, 0), hou.Vector3(0, 1, 0), origin, direction) return hou.Vector3(planePos)
def build_camera(json_file): with open(json_file, 'r') as f: json_data = json.load(f) obj_node = hou.node('/obj') cam_node = obj_node.createNode('cam', node_name=json_data['name']) logging.info('Building %s camera', json_data['name']) eye = hou.Vector3(json_data['eye']) up = hou.Vector3(json_data['up']) look = hou.Vector3(json_data['look']) cam_node.parmTuple('t').set(json_data['eye']) z = look - eye x = up.cross(z) y = z.cross(x) # x axis is flipped from houdini x = -x.normalized() y = y.normalized() z = z.normalized() mat3 = hou.Matrix3((x, y, z)) cam_node.parmTuple('r').set(mat3.extractRotates()) cam_node.parmTuple('res').set((2048, int(2048 * 1.0 / json_data['ratio']))) focal = json_data['focalLength'] cam_node.parm('focal').set(focal) fov_rad = math.radians(json_data['fov']) fov_ratio = (1.0 / math.tan(fov_rad * 0.5)) * 0.5 cam_node.parm('aperture').set(focal / fov_ratio) cam_node.parm('focus').set(json_data['centerOfInterest']) cam_node.parm('fstop').set(focal / (json_data['lensRadius'] * 2.0)) cam_node.parm('far').set(1.0e6) create_rop(cam_node)
def test_v3Project(self): v3 = hou.Vector3(-1.3, 0.5, 7.6) proj = v3.project(hou.Vector3(2.87, 3.1, -0.5)) result = hou.Vector3(-0.948531, -1.02455, 0.165249) self.assertTrue(proj.isAlmostEqual(result))
def test_computeIntersection(self): bbox1 = hou.BoundingBox(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5) bbox2 = hou.BoundingBox(0, 0, 0, 0.5, 0.5, 0.5) self.assertTrue(bbox1.computeIntersection(bbox2)) self.assertEqual(bbox1.minvec(), hou.Vector3()) self.assertEqual(bbox1.maxvec(), hou.Vector3(0.5, 0.5, 0.5))
def setTransform(self, pivot, scale): svec = hou.Vector3(scale, scale, scale) xform = hou.hmath.buildTransform({ 'translate': pivot, 'rotate': hou.Vector3(0, 0, 0), 'scale': svec }) self.knob_drawable.setTransform(xform)
def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer self.node = None self.collisiongeo = None self.multiparm = None self.placedobject = False self.placedpos = hou.Vector3() self.hitnormal = hou.Vector3()
def setNodeColor(applicationObject='', latest=True): latestColor = hou.Color(hou.Vector3(0.07, 0.63, 0.29)) oldColor = hou.Color(hou.Vector3(0.89, 0.39, 0.08)) for n in hou.node('/').allSubChildren(): if n.name() == applicationObject: if latest: n.setColor(latestColor) else: n.setColor(oldColor)
def test_buildLookat(self): TARGET = hou.Matrix3( ((0.70710678118654746, -0.0, 0.70710678118654746), (0.0, 1.0, 0.0), (-0.70710678118654746, 0.0, 0.70710678118654746))) lookAt = hou.hmath.buildLookat(hou.Vector3(0, 0, 1), hou.Vector3(1, 0, 0), hou.Vector3(0, 1, 0)) self.assertEqual(lookAt, TARGET)
def __resetSettings(self): self.mouse_screen = hou.Vector3() self.position = hou.Vector3() self.projected_position = hou.Vector3() self.normal = hou.Vector3(0, 0, 1) self.primuv = hou.Vector3() self.snapped = False self.snapped_ptnum = None self.snapped_edge = None self.snapped_prim = None
def cpSetOrigin(new_origin,construction_plane = []): if construction_plane == []: construction_plane = toolutils.sceneViewer().constructionPlane() # revert center offset t = hou.hmath.buildTranslate(hou.Vector3([-2,-2,0])) construction_plane.setTransform(t.inverted()*construction_plane.transform()) # process translation = hou.hmath.buildTranslate(hou.Vector3(new_origin) - cpOrigin(construction_plane)) construction_plane.setTransform(construction_plane.transform() * translation) # apply center offset construction_plane.setTransform(t*construction_plane.transform())
def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer self.poly_id = -1 self.cursor_text = "Text" self.geometry = None self.geometryHandles = None self.mouseStart = hou.Vector2() self.mouseXLast = -1 self.mouse_screen = hou.Vector2() self.cursorStartPos = hou.Vector3() self.dragStartValue = 0 self.handleStartPos = hou.Vector3() self.currentPoint = -1 self.currentHandleIdx = -1 self.currentPrimid = -1 self.currentPrimu = -1 self.currentPrimDist = -1 self.dragAction = False self.isHandle = False self.autoSlide = False self.slideHandlesAhead = False self.slideHandlesBehind = False self.handlePosMethod = 0 self.text = hou.TextDrawable(self.scene_viewer, "text") # Construct a geometry drawable group line = hou.GeometryDrawable(self.scene_viewer, hou.drawableGeometryType.Line, "line", params={ "color1": (0.0, 0.0, 1.0, 1.0), "style": hou.drawableGeometryLineStyle.Plain, "line_width": 3} ) face = hou.GeometryDrawable(self.scene_viewer, hou.drawableGeometryType.Face, "face", params={ "style": hou.drawableGeometryFaceStyle.Plain, "color1": (0.0, 1.0, 0.0, 1.0)} ) point = hou.GeometryDrawable(self.scene_viewer, hou.drawableGeometryType.Point, "point", params={ "num_rings": 2, "radius": 8, "color1": (1.0, 0.0, 0.0, 1.0), "style": hou.drawableGeometryPointStyle.LinearCircle} ) self.poly_guide = hou.GeometryDrawableGroup("poly_guide") self.poly_guide.addDrawable(face) self.poly_guide.addDrawable(line) self.poly_guide.addDrawable(point)
def onMouseEvent(self, kwargs): ui_event = kwargs["ui_event"] dev = ui_event.device() # ray cast origin, direction, snapped = ui_event.snappingRay() # selected geometry selectedGeometry = self.getSelectedGeometry() # no geometry selected, so no measurement if not selectedGeometry: return # get intersection position intersection = util.sopGeometryIntersection(selectedGeometry, origin, direction) intersectpos = intersection[1] if intersection[0] < 0: intersectpos = util.cplaneIntersection(self.scene_viewer, origin, direction) parentxform = ancestorObject(self.getSelectedNode()).worldTransform() if dev.isLeftButton(): self.measuremode = 0 if not self.clickstarted: self.startpos = intersectpos * parentxform self.clickstarted = True if not dev.isCtrlKey(): self.endpos1 = self.endpos2 = intersectpos * parentxform else: self.measuremode = 1 self.endpos2 = intersectpos * parentxform else: self.clickstarted = False distance1 = self.startpos.distanceTo(self.endpos1) distance2 = self.startpos.distanceTo(self.endpos2) drawdirection1 = hou.Vector3(self.endpos1 - self.startpos).normalized() drawdirection2 = hou.Vector3(self.endpos2 - self.startpos).normalized() self.drawable1.setTransform(self.createGuideTransform(self.startpos, drawdirection1, distance1)) self.drawable2.setTransform(self.createGuideTransform(self.startpos, drawdirection2, distance2)) # Screen Messages self.scene_viewer.clearPromptMessage() if self.measuremode == 0: self.scene_viewer.setPromptMessage("Distance: %.3f" % round(distance1, 3)) else: angle = math.degrees(math.acos(round(drawdirection1.dot(drawdirection2), 5))) self.scene_viewer.setPromptMessage("Angle: %.2f Degrees" % round(angle, 2))
def testCannotTransformRest( self ) : sop = self.emptySop() mergeGeo = hou.node( "/obj" ).createNode( "geo", run_init_scripts=False ) mergeGeo.parm( "tx" ).set( 10 ) merge = mergeGeo.createNode( "object_merge" ) merge.parm( "xformtype" ).set( 1 ) merge.parm( "objpath1" ).set( sop.path() ) mesh = IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( 0 ), imath.V2f( 1 ) ) ) IECoreScene.TriangulateOp()( input=mesh, copyInput=False ) IECoreScene.MeshNormalsOp()( input=mesh, copyInput=False ) mesh["Pref"] = mesh["P"] prefData = mesh["Pref"].data self.assertTrue( mesh.arePrimitiveVariablesValid() ) converter = IECoreHoudini.ToHoudiniPolygonsConverter( mesh ) self.assertTrue( converter.convert( sop ) ) geo = sop.geometry() geo2 = merge.geometry() i = 0 for point in geo.points() : restValue = point.attribValue( "rest" ) self.assertAlmostEqual( imath.V3f( restValue[0], restValue[1], restValue[2] ), prefData[i] ) self.assertTrue( point.position().isAlmostEqual( hou.Vector3(restValue) ) ) i += 1 i = 0 for point in geo2.points() : restValue = point.attribValue( "rest" ) self.assertAlmostEqual( imath.V3f( restValue[0], restValue[1], restValue[2] ), prefData[i] ) self.assertFalse( point.position().isAlmostEqual( hou.Vector3(restValue) ) ) i += 1 # Pref shouldn't transform either converter["convertStandardAttributes"].setTypedValue( False ) self.assertTrue( converter.convert( sop ) ) geo = sop.geometry() geo2 = merge.geometry() i = 0 for point in geo.points() : restValue = point.attribValue( "Pref" ) self.assertAlmostEqual( imath.V3f( restValue[0], restValue[1], restValue[2] ), prefData[i] ) self.assertTrue( point.position().isAlmostEqual( hou.Vector3(restValue) ) ) i += 1 i = 0 for point in geo2.points() : restValue = point.attribValue( "Pref" ) self.assertAlmostEqual( imath.V3f( restValue[0], restValue[1], restValue[2] ), prefData[i] ) self.assertFalse( point.position().isAlmostEqual( hou.Vector3(restValue) ) ) i += 1
def test_clipBelow(self): geo = getObjGeoCopy("test_clipBelow") origin = hou.Vector3(0, -0.7, -0.9) direction = hou.Vector3(-0.6, 0.1, -0.8) geo.clip(origin, direction, 0.6, below=True) self.assertEqual(len(geo.iterPrims()), 61) self.assertEqual(len(geo.iterPoints()), 81)
def test_clip(self): geo = getObjGeoCopy("test_clip") origin = hou.Vector3(0, 0, 0) direction = hou.Vector3(-0.5, 0.6, -0.6) geo.clip(origin, direction, 0.5) self.assertEqual(len(geo.iterPrims()), 42) self.assertEqual(len(geo.iterPoints()), 60)
def test_buildInstance(self): TARGET = hou.Matrix4( ((1.0606601717798214, -1.0606601717798214, 0.0, 0.0), (0.61237243569579436, 0.61237243569579436, -1.2247448713915889, 0.0), (0.86602540378443882, 0.86602540378443882, 0.86602540378443882, 0.0), (-1.0, 2.0, 4.0, 1.0))) mat = hou.hmath.buildInstance(hou.Vector3(-1, 2, 4), hou.Vector3(1, 1, 1), pscale=1.5, up=hou.Vector3(1, 1, -1)) self.assertEqual(mat, TARGET)
def getHandleTRS(parms): rotate = hou.Vector3(parms['rx'], parms['ry'], parms['rz']) if parms.has_key('tx'): translate = hou.Vector3(parms['tx'], parms['ty'], parms['tz']) scale = hou.Vector3(parms['sx'], parms['sy'], parms['sz']) else: translate = hou.Vector3(parms['centerx'], parms['centery'], parms['centerz']) scale = hou.Vector3(parms['sizex'], parms['sizey'], parms['sizez']) return {'translate': translate, 'rotate': rotate, 'scale': scale}
def __init__(self, scene_viewer, color, show_text, text_scale): line = createLineGeometry() frustum = createFrustumGeometry() self.color = color self.disk_x = Measurement.disk_maker.makeDisk((1, 0, 0), (.7, .2, .2)) self.disk_y = Measurement.disk_maker.makeDisk((0, 1, 0), (.2, .7, .2)) self.disk_z = Measurement.disk_maker.makeDisk((0, 0, 1), (.2, .2, .7)) self.scene_viewer = scene_viewer self.tail_spot_drawable = hou.GeometryDrawable( scene_viewer, hou.drawableGeometryType.Line, "tail_spot", frustum) self.head_spot_drawable = hou.GeometryDrawable( scene_viewer, hou.drawableGeometryType.Line, "head_spot", frustum) self.line_drawable = hou.GeometryDrawable( scene_viewer, hou.drawableGeometryType.Line, "line", line) self.tail_disk_drawable = None self.head_disk_drawable = None self.text_drawable = hou.TextDrawable(scene_viewer, "text_drawable") self.text_params = { 'text': None, 'translate': hou.Vector3(0.0, 0.0, 0.0), 'highlight_mode': hou.drawableHighlightMode.MatteOverGlow, 'glow_width': 10, 'color2': hou.Vector4(0, 0, 0, 0.5), 'scale': hou.Vector3(text_scale, text_scale, text_scale) } self.spot_params = { 'color1': color.getVec(), 'fade_factor': 0.5, 'highlight_mode': hou.drawableHighlightMode.MatteOverGlow, 'glow_width': 5 } self.line_params = { 'line_width': 4.0, 'style': (10.0, 5.0), 'color1': color.getVec(), 'fade_factor': 0.3, 'highlight_mode': hou.drawableHighlightMode.MatteOverGlow, 'glow_width': 5 } self.tail_pos = hou.Vector3(0.0, 0.0, 0.0) self.head_pos = hou.Vector3(0.0, 0.0, 0.0) self.spot_size = 0.01 self.measurement = 0.0 self.font_size = Measurement.default_font_size self.font_color = color.getHexStr() self.text = Measurement.default_text self.curPlane = None self.angle_snapping = False self.name = "" self.show_text = show_text self.updateTextField()
def test_clipGroup(self): geo = getObjGeoCopy("test_clipGroup") group = geo.primGroups()[0] origin = hou.Vector3(-1.3, -1.5, 1.2) direction = hou.Vector3(0.8, 0.02, 0.5) geo.clip(origin, direction, -0.3, group=group) self.assertEqual(len(geo.iterPrims()), 74) self.assertEqual(len(geo.iterPoints()), 98)
def setTransform(self, pivot, scale, normal=None): svec = hou.Vector3(scale, scale, scale) if normal: xform = hou.Vector3(0, 0, 1).matrixToRotateTo(normal) xform *= hou.hmath.buildTranslate(pivot) xform = xform.preMult(hou.hmath.buildScale(svec)) else: xform = hou.hmath.buildTransform({ 'translate': pivot, 'rotate': hou.Vector3(0, 0, 0), 'scale': svec }) self.drawable.setTransform(xform) self.knob_drawable.setTransform(xform)
def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer self.startpos = hou.Vector3() self.endpos1 = hou.Vector3() self.endpos2 = hou.Vector3() self.clickstarted = False self.guide_geo1 = None self.drawable1 = None self.guide_geo2 = None self.drawable2 = None self.measuremode = 0 # 0 = distance, 1 = angle self.initializeDrawable()
def doOperation(self, args): # take a copy of our input parameter prim = args['input'].copy() # check for P & N if not "P" in prim: raise Exception("Must have primvar 'P' in primitive!") if not "N" in prim: error("Must have primvar 'N' in primitive!") return # get our magnitude & frequency parameters mag = args['magnitude'].value freq = args['frequency'].value # calculate a new set of positions p_data = prim['P'].data new_p = [] for p in p_data: noise_val = mag * ( hou.hmath.noise3d([p.x * freq.x, p.y * freq.y, p.z * freq.z]) - hou.Vector3(.5, .5, .5)) * 2 new_p.append(p + V3f(noise_val[0], noise_val[1], noise_val[2])) # overwrite with our new P and return from the Op prim['P'] = PrimitiveVariable(PrimitiveVariable.Interpolation.Vertex, V3fVectorData(new_p)) # recalculate normals if prim.typeId() == TypeId.MeshPrimitive: MeshNormalsOp()(input=prim, copyInput=False) return prim
def intersectWithPlane(self, origin, ray): rot = hou.Matrix4.extractRotationMatrix3(g_WorldXform) plane = State.planes[self.curPlane] * rot.inverted() planePoint = hou.Vector3(0, 0, 0) * g_WorldXform.inverted() return Intersection( hou.hmath.intersectPlane(planePoint, plane, origin, ray), self.curPlane)
def GetBoneEndPos(boneNode): if boneNode: worldTrans = boneNode.worldTransform() #return (worldTrans.at(3, 0), worldTrans.at(3, 1), worldTrans.at(3, 2)) boneLength = boneNode.parm('length').eval() localOffset = hou.Vector3(0, 0, -boneLength) return localOffset * worldTrans
def test_baryCenter(self): TARGET = hou.Vector3(1.5, 1, -1) geo = getObjGeoCopy("test_baryCenter") prim = geo.iterPrims()[0] self.assertEqual(prim.baryCenter(), TARGET)
def weighted_function(eo_new): eo_new = hou.Vector3(eo_new) res = (w1 * math.pow( (2 * normal_c.dot(eo_new)) / math.pow(eo_new.length(), 2) - taubin_curvature, 2) + w2 * math.pow( (eo_new - eo_prev).length(), 2)) return res
def optimize_new_point(self, p, p_1, p_2, new_points, normal_c): # 1. Compute the Taubin Curvature # NOTE: ALL_N,E elem R^3, N^T * E == N.E, so we use RHS intead e1, e2 = p_1.position() - p.position(), p_2.position() - p.position() taubin_curvature = (normal_c.dot(e1) / math.pow(e1.length(), 2) + normal_c.dot(e2) / math.pow(e2.length(), 2)) # 2. Solve for eo_new, through minimizing F(eo_new) for new_point in new_points: eo_prev = new_point.position() - p.position() def weighted_function(eo_new): eo_new = hou.Vector3(eo_new) res = (w1 * math.pow( (2 * normal_c.dot(eo_new)) / math.pow(eo_new.length(), 2) - taubin_curvature, 2) + w2 * math.pow( (eo_new - eo_prev).length(), 2)) return res eo_new = hou.Vector3( minimize(weighted_function, np.array(eo_prev))[0]) # 3. Calculate optimal new_point new_point.setPosition(p.position() + eo_new) # 4. Recalculate changed vertex normals for new_point in new_points: get_normal(self.geo, new_point)