using System;
using Rhino;
using Rhino.Commands;
using Rhino.DocObjects;
using Rhino.Geometry;
using Rhino.Input;
using Rhino.Input.Custom;
using Rhino.Render;
Result ApplyWcsTest(RhinoDoc doc)
{
// Select an object with a texture
if (RhinoGet.GetOneObject("Select an object with a texture", false, ObjectType.AnyObject, out ObjRef objRef)!=Result.Success)
return Result.Failure;
// Get the selected RhinoObject
var obj = objRef.Object();
if (obj == null)
return Result.Failure;
// Fetch the texture from the selected object's RenderMaterial
var objRenderMaterial = obj.RenderMaterial;
if (objRenderMaterial == null)
{
RhinoApp.WriteLine("The selected object has no render material.");
return Result.Failure;
}
// Get the texture associated with the Diffuse channel
var texture = objRenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.Diffuse);
if (texture == null)
{
RhinoApp.WriteLine("No texture found on the selected object's diffuse channel.");
return Result.Failure;
}
// Define the origin plane for the OCS texture mapping
var ocsOriginPlane = Plane.WorldXY;
// Set up OCS texture mapping
texture.SetProjectionMode(TextureProjectionMode.WcsBox, RenderContent.ChangeContexts.Ignore);
float size = 100;
texture.SetRepeat(new Vector3d(1/size, 1/size, 0), RenderContent.ChangeContexts.Ignore);
// Set the texture mapping to the object
obj.RenderMaterial = objRenderMaterial;
obj.CommitChanges();
doc.Views.Redraw();
return Result.Success;
}
ApplyWcsTest(RhinoDoc.ActiveDoc);
After reading that link, I guess the more appropriate question to ask might be - how to define an ocs frame on an object mapping channel (per object) ?
In that case you need to figure out the orientation of your object first and align it to that, I think, but I might be missing something.
Are you expecting that the texture stays aligned with the object when you rotate it?
@Gijs
Yes, I want the texture to stay aligned with the object.
Which I have been able to achieve in Rhino by using ApplyOcsMapping Command.
Essentially it lets me define a plane (i think) and then orients the material when the object is transformed (scaled, rotated etc.)
I have found a way to define a plane aligned with the object.
// create ocs mapping
var ocsFrame = /* example plane oriented to the object face*/;
var ocsMapping = TextureMapping.CreateOcsMapping(ocsFrame);
// set ocs mapping for object
var ocsMappingChannel = ObjectAttributes.OCSMappingChannelId;
rhinoObj.SetTextureMapping(ocsMappingChannel, ocsMapping);
rhinoObj.CommitChanges();
doc.Views.Redraw();
I am getting the ocsframe from the front face of the box. essentially i use the brepface and get plane from there.
The sample code above sets the object mapping channel of type Planar instead of OCS frame.
found something interesting.
CreateOcsMapping method creates a TextureMapping object of TextureMappingType.PlaneMapping instead of TextureMappingType.OcsMapping
Not sure if thats intentional and I am missing something.
OCS Mapping is essentially a plane - it expresses the frame. It is interpreted as OCS frame when it is set in OCSMappingChannelId - this is the same for any object that wants an OCS frame set. And there can be only one per object.
It is a bit hacky, but that is how OCS frame is set on an object.