Hi everyone.
I receiveid a exported project which the objects colors are set as "By block", but it does have a color.
I'm not shure how to discover if the faces are "painted" with the color face sub-command, but slicing it, the new faces receive the White color (Byblock) so I'm almost certain of this.
My goal is to get the color of any face of each object and turn it the color of the main object itself.
I think the way is to convert the set of faces of each object into a list and get the head of this list, then the color, but I don't know how to get this properties.
As it is a lot of objects, my intent is to not select the object for geting the face, I'll use the entire drawing selection (as the colors are result of an exportation it is consistently painted so doesn't matter which face I select).
Getting this result I'm able to convert the color to a layer with one code I already have.
TIA
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Unfortunately, the entity data for 3D Solids is utterly inscrutable, so I'm not sure it's possible to pull things like that out of it. I tried giving some distinctive color numbers to faces of a 3D Solid, and couldn't find those numbers anywhere in entity data, nor in VLA properties, nor in (getpropertyvalue) properties, nor in extended data [that coloring doesn't create any]. I don't know where else to look for it, but maybe it's available somehow.
What does a dxfout of a 3d object reveal ? ACIS solid details comes to mine a huge minefield of information. To confusing for this average person.
A Google "spatial's acis solid modeling format" lots of info.
Hi,
As said by @Kent1Cooper and @Sea-Haven this cannot be done with LISP, but it is doable with .NET.
Here's an example which defines a RESETFACESCOLOR command.
C# code:
using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Linq;
namespace SolidFacesColorSample
{
public class Commands
{
[CommandMethod("RESETFACESCOLOR")]
public void ResetFacesColor()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var filter = new SelectionFilter(new[] { new TypedValue(0, "3DSOLID") });
var selection = ed.GetSelection(filter);
if (selection.Status == PromptStatus.OK)
{
using (var tr = db.TransactionManager.StartTransaction())
{
foreach (var id in selection.Value.GetObjectIds())
{
var solid = (Solid3d)tr.GetObject(id, OpenMode.ForWrite);
SetFacesColor(solid, solid.Color);
}
tr.Commit();
}
}
}
private static void SetFacesColor(Solid3d solid, Color color)
{
var fullSubentityPath = new FullSubentityPath(
new[] { solid.ObjectId },
new SubentityId(SubentityType.Null, IntPtr.Zero));
using (var brep = new Brep(fullSubentityPath))
{
var subentIds = brep.Faces
.Select(f => f.SubentityPath.SubentId)
.ToArray();
foreach (var subentId in subentIds)
{
solid.SetSubentityColor(subentId, color);
}
}
}
}
}
If you trust me enough to download and run a compiled application (I think you can):
Great answer Gile, a typo in the instructions maybe, we all make them, our brain thinks faster than we type.
@Sea-Haven wrote:
Great answer Gile, a typo in the instructions maybe, we all make them, our brain thinks faster than we type.
- Run the RESETFALCESCOLOR command.
- should it be ?
- Run the RESETFACESCOLOR command.
Thanks for reporting, I'll correct my reply.
Anyway, I was wrong, it can be done with LISP by sripting the SOLIDEDIT command. The following code should work in most of the cases (the solid centroid have to be projected on a face of the solid according to the view).
EDIT: wrap the (command ...) in a (vl-catch-all-apply ...) expression so that the routinedoes not stop if it fail for some solid.
(defun c:SetFacesByBlock (/ getCentroid ss i)
(defun getCentroid (solid)
(trans (vlax-get (vlax-ename->vla-object solid) 'Centroid) 0 1)
)
(if (setq ss (ssget '((0 . "3DSOLID"))))
(repeat (setq i (sslength ss))
(vl-catch-all-apply
'(lambda (/ solid point)
(setq solid (ssname ss (setq i (1- i)))
point (getCentroid solid)
)
(command-s "_.solidedit"
"_face"
"_color"
point
"_all"
""
"ByBlock"
""
""
)
)
)
)
)
(princ)
)
But I believe they are not trying to assign "ByBlock" to all faces, but to extract the color assigned to a face, and assign that as a property of the overall object, not its faces. @gustavobernardi, am I correct about that?
@Kent1Cooper wrote:
But I believe they are not trying to assign "ByBlock" to all faces, but to extract the color assigned to a face, and assign that as a property of the overall object, not its faces. @gustavobernardi, am I correct about that?
Oops! I misunderstood the request (my English is not that good...)
Attached a new DLL with an additional command: SETCOLORFROMFACE which set the color of the selected solids with color ByBlock to the first find face color (if any).
[CommandMethod("SETCOLORFROMFACE")]
public static void SetColorFromFace()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var filter = new SelectionFilter(new[] {
new TypedValue(0, "3DSOLID"),
new TypedValue(62, 0)});
var selection = ed.GetSelection(filter);
if (selection.Status == PromptStatus.OK)
{
using (var tr = db.TransactionManager.StartTransaction())
{
foreach (var id in selection.Value.GetObjectIds())
{
var solid = (Solid3d)tr.GetObject(id, OpenMode.ForRead);
if (TryGetFaceColor(solid, out Color color))
{
tr.GetObject(id, OpenMode.ForWrite);
solid.Color = color;
}
}
tr.Commit();
}
}
}
private static bool TryGetFaceColor(Solid3d solid, out Color color)
{
color = default;
var fullSubentityPath = new FullSubentityPath(
new[] { solid.ObjectId },
new SubentityId(SubentityType.Null, IntPtr.Zero));
using (var brep = new Brep(fullSubentityPath))
{
var subentIds = brep.Faces
.Select(f => f.SubentityPath.SubentId)
.ToArray();
foreach (var subentId in subentIds)
{
try
{
color = solid.GetSubentityColor(subentId);
break;
}
catch { }
}
}
return color != default;
}
Can't find what you're looking for? Ask the community or share your knowledge.