TopoDS_Shape and BRepBuilderAPI_Transform.

Hey.

When I create TopoDS_Shape, I add the created object in the vector.
Then, when I select the object I sort out the array and to check whether there is in it the selected object using isSame or isEqual function. This works fine.
But when I change the size of the object.
gp_Trsf myTrsf;
myTrsf.SetScale (gp_Pnt (xMin, yMin, zMin), 50);
BRepBuilderAPI_Transform bTransf (shape, myTrsf);

My code does not work anymore, because the function isSame does not return True now.
Tell me what to do?
Perhaps my error method.
Tell me how to better identify TopoDS_Shape? I have several objects TopoDS_Shape, but some of them have to be unique.

Roman's picture

Now I checked HashCode object in Vector and selected. They differ!!!
This happens after I call the function anIS-> Redisplay (); when the object of transformation.
But if I do not call the function that is the problem described in this topic http://www.opencascade.com/content/simple-object-transformations
What to do?

Guido van Hilst not specified's picture

Using BRepBuilderAPI_Transform

Depending of the type of transformation and the "copy" flag in the constructor of BRepBuilderAPI_Transform, there is a new  underlying​ TopoDS_TShape created, or the existing TopoDS_TShape is used.

If "copy" is true there is always a new TShape created. if "copy" is false then it depends of the type of transformation if a new TShape is created.

If the transformation T is direct and isometric, in other words, if the determinant of the vectorial part of T is equal to 1., and if Copy equals false (the default value), the resulting shape is  the same as the original but with a new location assigned to it.In all other cases, the transformation is applied to a duplicate of S

For example the following transformation does not modify the TShape: (IsPartner = true)

OCgp_Vec v = new OCgp_Vec(1, 0, 0);

OCgp_Trsf t = new OCgp_Trsf();

t.SetTranslationPart(v);

But.

t,SetScale(new OCgp_Pnt(0, 0, 0), 10.0); DOES create a new TShape when using BRepBuilderAPI_Transform even when "copy" is to false. ( (IsPartner = false)

Using TopoDS_Shape::Located

 When using TopoDS_Shape::Located(TopLoc_Location Loc); you always get a shape with the same underlying TShape. (IsPartner is always true when using Located)

TopoDS_Shape::Located does not depend on the type of transformation

below is a test-case where differences in behavior of  BRepBuilderAPI_Transform  and TopoDS_Shape::Located(..) is shown

   /// <summary>
        ///A test for TopoDS_Shape IsSame
        ///</summary>
        [TestMethod()]
        [TestCategory(TestCategories.OCC)]
        public void IsSame_TopoDS_Shape_Test()
        {

            OCTopoDS_Shape shape1 = new OCBRepPrimAPI_MakeBox(2, 5, 6).Shape();
            OCTopoDS_Shape shape2 = shape1.Located(shape1.Location());

            Assert.IsTrue(shape1.IsPartner(shape2));
            Assert.IsTrue(shape1.IsSame(shape2));
            Assert.IsTrue(shape1.IsEqual(shape2));

            OCgp_Vec v = new OCgp_Vec(1, 0, 0);

            OCgp_Trsf t = new OCgp_Trsf();
            t.SetTranslationPart(v);

            OCTopoDS_Shape newShape1 = shape1.Located(new OCTopLoc_Location(t));

            Assert.IsTrue(shape1.IsPartner(newShape1));
            Assert.IsFalse(shape1.IsSame(newShape1));
            Assert.IsFalse(shape1.IsEqual(newShape1));

            t = new OCgp_Trsf();
            t.SetScale(new OCgp_Pnt(0, 0, 0), 10.0);

            newShape1 = shape1.Located(new OCTopLoc_Location(t));

            Assert.IsTrue(shape1.IsPartner(newShape1));
            Assert.IsFalse(shape1.IsSame(newShape1));
            Assert.IsFalse(shape1.IsEqual(newShape1));
           

            t = new OCgp_Trsf();
            t.SetTranslationPart(v);

            bool copyGeometry = false;
            OCTopoDS_Shape newShape2 = new OCBRepBuilderAPI_Transform(shape1, t, copyGeometry).Shape();
            Assert.IsTrue(shape1.IsPartner(newShape2));
            Assert.IsFalse(shape1.IsSame(newShape2));
            Assert.IsFalse(shape1.IsEqual(newShape2));

            copyGeometry = true;
            newShape2 = new OCBRepBuilderAPI_Transform(shape1, t, copyGeometry).Shape();
            Assert.IsFalse(shape1.IsPartner(newShape2));
            Assert.IsFalse(shape1.IsSame(newShape2));
            Assert.IsFalse(shape1.IsEqual(newShape2));

            
            t = new OCgp_Trsf();
            t.SetScale(new OCgp_Pnt(0, 0, 0), 10.0);

            copyGeometry = false;
            newShape2 = new OCBRepBuilderAPI_Transform(shape1, t, copyGeometry).Shape();
            Assert.IsFalse(shape1.IsPartner(newShape2));
            Assert.IsFalse(shape1.IsSame(newShape2));
            Assert.IsFalse(shape1.IsEqual(newShape2));

            copyGeometry = true;
            newShape2 = new OCBRepBuilderAPI_Transform(shape1, t, copyGeometry).Shape();
            Assert.IsFalse(shape1.IsPartner(newShape2));
            Assert.IsFalse(shape1.IsSame(newShape2));
            Assert.IsFalse(shape1.IsEqual(newShape2));

        }

Roman's picture

Guido van Hilst thank you.
I have done differently, I re-create the object and add it again in the array, and the old object is removed. I will definitely take advantage of your solution in the future if I need to.

[offtop] Tell me how to set the color for TopoDS_Shape?
I tried this:
TopoDS_Shape sphere = BRepPrimAPI_MakeSphere (gp_Pnt (posX, posY, posZ), rad);
XCAFDoc_ColorTool sphereColor;
Quantity_Color col (Quantity_NOC_WHITE);
sphereColor.SetColor (sphere, col, XCAFDoc_ColorType :: XCAFDoc_ColorGen);
But it does not work.

Guido van Hilst not specified's picture

Hi Roman,

It depends of what you mean with "set the color for TopoDS_Shape"?

Do you mean set the color of the shape in an Ocaf document(like set the color in a step file)

Or do you mean set the color to display in the view?

Below is a code snipped that show how to set the colors of shapes in an Ocaf document and save it as a STEP file:

(see attachments test.step and color_box_stepfile.JPG

    public void TestWriteStepfileWithColors()
        {
            OCTopoDS_Shape box = new OCBRepPrimAPI_MakeBox(2, 5, 6).Shape();
            StepItem shapeItem = new StepItem() { Shape = box, Name = "box" };

            List<OCTopoDS_Face> faces = box.Faces().ToList();

            Debug.Assert(faces.Count == 6);

            shapeItem.AddSubItem(new StepItem() { Name = "face0", Shape = faces[0], Color = Color.Blue });
            shapeItem.AddSubItem(new StepItem() { Name = "face1", Shape = faces[1], Color = Color.Green });
            shapeItem.AddSubItem(new StepItem() { Name = "face2", Shape = faces[2], Color = Color.Yellow });
            shapeItem.AddSubItem(new StepItem() { Name = "face3", Shape = faces[3], Color = Color.Red });
            shapeItem.AddSubItem(new StepItem() { Name = "face4", Shape = faces[4], Color = Color.Orange });
            shapeItem.AddSubItem(new StepItem() { Name = "face5", Shape = faces[5], Color = Color.Magenta });

            STEPWriter.Write(shapeItem, @"c:\test.step");

            //OCAFBrowser.ShowStepOcafTree(@"c:\test.step");

        }

using CCT.OCDotNet;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace StepWriterTest
{
    public class StepItem
    {
        public OCTopoDS_Shape Shape;
        public Color? Color;
        public string Name;
        public OCXCAFDoc_ColorType ColorType= OCXCAFDoc_ColorType.XCAFDoc_ColorGen;
        public List<StepItem> SubItems;

        /// <summary>
        /// Shape of subItem should be a subshape of the parent shape
        /// </summary>
        /// <param name="subItem"></param>
        public void AddSubItem(StepItem subItem)
        {
            if (SubItems == null) SubItems = new List<StepItem>();

            SubItems.Add(subItem);
        }

        public bool HasSubItems
        {
            get { return SubItems != null && SubItems.Count > 0; }
        }

        public bool HasColor
        {
            get { return Color != null && Color.HasValue; }
        }

        public bool HasName
        {
            get { return !string.IsNullOrEmpty(Name); }
        }
    }

    public class STEPWriter
    {
        public static bool Write(IEnumerable<StepItem> items, string filename)
        {
            STEPWriter w = new STEPWriter();
            return w.WriteStepfile(items, filename);
        }

        public static bool Write(StepItem item, string filename)
        {
            return STEPWriter.Write(new StepItem[] { item }, filename);
          
        }

        OCTDocStd_Document _document;
        OCTDF_Label _mainLabel;
        OCXCAFDoc_ShapeTool _shapeTool;
        OCXCAFDoc_ColorTool _colorTool;

        private bool WriteStepfile(IEnumerable<StepItem> items, string filename)
        {
            _document = new OCTDocStd_Document(new OCTCollection_ExtendedString("DocType"));

            OCXCAFDoc_ShapeTool.SetAutoNaming(true);

            _mainLabel = _document.Main();
            _shapeTool = OCXCAFDoc_DocumentTool.ShapeTool(_mainLabel);
            _colorTool = OCXCAFDoc_DocumentTool.ColorTool(_mainLabel);

            foreach (StepItem stepItem in items)
            {
                AddItem(stepItem);
            }

            OCSTEPCAFControl_Writer writer = new OCSTEPCAFControl_Writer();
            writer.SetNameMode(true);
            writer.SetColorMode(true);
            writer.SetLayerMode(true);
            writer.SetPropsMode(true);
            writer.SetSHUOMode(true);

            writer.Transfer(_document, OCSTEPControl_StepModelType.STEPControl_AsIs);
            OCIFSelect_ReturnStatus ret = writer.Write(filename);
        
            return ret == OCIFSelect_ReturnStatus.IFSelect_RetDone;
        }

        private void AddItem(StepItem stepItem)
        {
            OCTDF_Label shapeLabel = _shapeTool.AddShape(stepItem.Shape, true, true);

            SetShapeLabel(shapeLabel, stepItem);
        }

        private void SetShapeLabel(OCTDF_Label shapeLabel, StepItem stepItem)
        {
            if (shapeLabel == null || shapeLabel.IsNull())
                return;

            OCXCAFDoc_ShapeMapTool shapeMap = OCXCAFDoc_ShapeMapTool.Set(shapeLabel);
            shapeMap.SetShape(stepItem.Shape);

            if (stepItem.HasName)
            {
                OCTDataStd_Name.Set(shapeLabel, new OCTCollection_ExtendedString(stepItem.Name));
            }

            if (stepItem.HasColor)
            {
                _colorTool.SetColor(shapeLabel, stepItem.Color.Value.ToOCCColor(), stepItem.ColorType);
                _colorTool.AddColor(stepItem.Color.Value.ToOCCColor());
                
            }

            if (stepItem.HasSubItems)
            {

                foreach (StepItem subStepItem in stepItem.SubItems)
                {
                    OCTDF_Label subShapeLabel = _shapeTool.AddSubShape(shapeLabel, subStepItem.Shape);
                    SetShapeLabel(subShapeLabel, subStepItem);
                }
            }
        }

    }
}

Guido van Hilst not specified's picture

Hi Roman,

It depends of what you mean with "set the color for TopoDS_Shape"?

Do you mean set the color of the shape in an Ocaf document(like set the color in a step file)

Or do you mean set the color to display in the view?

Below is a code snipped that show how to set the colors of shapes in an Ocaf document and save it as a STEP file:

(see attachments test.step and color_box_stepfile.JPG

    public void TestWriteStepfileWithColors()
        {
            OCTopoDS_Shape box = new OCBRepPrimAPI_MakeBox(2, 5, 6).Shape();
            StepItem shapeItem = new StepItem() { Shape = box, Name = "box" };

            List<OCTopoDS_Face> faces = box.Faces().ToList();

            Debug.Assert(faces.Count == 6);

            shapeItem.AddSubItem(new StepItem() { Name = "face0", Shape = faces[0], Color = Color.Blue });
            shapeItem.AddSubItem(new StepItem() { Name = "face1", Shape = faces[1], Color = Color.Green });
            shapeItem.AddSubItem(new StepItem() { Name = "face2", Shape = faces[2], Color = Color.Yellow });
            shapeItem.AddSubItem(new StepItem() { Name = "face3", Shape = faces[3], Color = Color.Red });
            shapeItem.AddSubItem(new StepItem() { Name = "face4", Shape = faces[4], Color = Color.Orange });
            shapeItem.AddSubItem(new StepItem() { Name = "face5", Shape = faces[5], Color = Color.Magenta });

            STEPWriter.Write(shapeItem, @"c:\test.step");

            //OCAFBrowser.ShowStepOcafTree(@"c:\test.step");

        }

using CCT.OCDotNet;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace StepWriterTest
{
    public class StepItem
    {
        public OCTopoDS_Shape Shape;
        public Color? Color;
        public string Name;
        public OCXCAFDoc_ColorType ColorType= OCXCAFDoc_ColorType.XCAFDoc_ColorGen;
        public List<StepItem> SubItems;

        /// <summary>
        /// Shape of subItem should be a subshape of the parent shape
        /// </summary>
        /// <param name="subItem"></param>
        public void AddSubItem(StepItem subItem)
        {
            if (SubItems == null) SubItems = new List<StepItem>();

            SubItems.Add(subItem);
        }

        public bool HasSubItems
        {
            get { return SubItems != null && SubItems.Count > 0; }
        }

        public bool HasColor
        {
            get { return Color != null && Color.HasValue; }
        }

        public bool HasName
        {
            get { return !string.IsNullOrEmpty(Name); }
        }
    }

    public class STEPWriter
    {
        public static bool Write(IEnumerable<StepItem> items, string filename)
        {
            STEPWriter w = new STEPWriter();
            return w.WriteStepfile(items, filename);
        }

        public static bool Write(StepItem item, string filename)
        {
            return STEPWriter.Write(new StepItem[] { item }, filename);
          
        }

        OCTDocStd_Document _document;
        OCTDF_Label _mainLabel;
        OCXCAFDoc_ShapeTool _shapeTool;
        OCXCAFDoc_ColorTool _colorTool;

        private bool WriteStepfile(IEnumerable<StepItem> items, string filename)
        {
            _document = new OCTDocStd_Document(new OCTCollection_ExtendedString("DocType"));

            OCXCAFDoc_ShapeTool.SetAutoNaming(true);

            _mainLabel = _document.Main();
            _shapeTool = OCXCAFDoc_DocumentTool.ShapeTool(_mainLabel);
            _colorTool = OCXCAFDoc_DocumentTool.ColorTool(_mainLabel);

            foreach (StepItem stepItem in items)
            {
                AddItem(stepItem);
            }

            OCSTEPCAFControl_Writer writer = new OCSTEPCAFControl_Writer();
            writer.SetNameMode(true);
            writer.SetColorMode(true);
            writer.SetLayerMode(true);
            writer.SetPropsMode(true);
            writer.SetSHUOMode(true);

            writer.Transfer(_document, OCSTEPControl_StepModelType.STEPControl_AsIs);
            OCIFSelect_ReturnStatus ret = writer.Write(filename);
        
            return ret == OCIFSelect_ReturnStatus.IFSelect_RetDone;
        }

        private void AddItem(StepItem stepItem)
        {
            OCTDF_Label shapeLabel = _shapeTool.AddShape(stepItem.Shape, true, true);

            SetShapeLabel(shapeLabel, stepItem);
        }

        private void SetShapeLabel(OCTDF_Label shapeLabel, StepItem stepItem)
        {
            if (shapeLabel == null || shapeLabel.IsNull())
                return;

            OCXCAFDoc_ShapeMapTool shapeMap = OCXCAFDoc_ShapeMapTool.Set(shapeLabel);
            shapeMap.SetShape(stepItem.Shape);

            if (stepItem.HasName)
            {
                OCTDataStd_Name.Set(shapeLabel, new OCTCollection_ExtendedString(stepItem.Name));
            }

            if (stepItem.HasColor)
            {
                _colorTool.SetColor(shapeLabel, stepItem.Color.Value.ToOCCColor(), stepItem.ColorType);
                _colorTool.AddColor(stepItem.Color.Value.ToOCCColor());
                
            }

            if (stepItem.HasSubItems)
            {

                foreach (StepItem subStepItem in stepItem.SubItems)
                {
                    OCTDF_Label subShapeLabel = _shapeTool.AddSubShape(shapeLabel, subStepItem.Shape);
                    SetShapeLabel(subShapeLabel, subStepItem);
                }
            }
        }

    }
}

Guido van Hilst not specified's picture

Hi Roman,

It depends on what you mean with "set the color for TopoDS_Shape"

If you want to visualize the shape in the view you should use:

OCAIS_Shape aisShape = new OCAIS_Shape(myShape);
s.SetColor(myColor);

If you want to set the color of a shape in a OCAF document (e.g. stepfile)

You can use the following: (in c#, but can easaly be ported to c++)

using CCT.OCDotNet;

using System;

using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace STepFileWriteTest
{
    public class StepItem
    {
        public OCTopoDS_Shape Shape;
        public Color? Color;
        public string Name;
        public OCXCAFDoc_ColorType ColorType= OCXCAFDoc_ColorType.XCAFDoc_ColorGen;
        public List<StepItem> SubItems;

        /// <summary>
        /// Shape of subItem should be a subshape of the parent shape
        /// </summary>
        /// <param name="subItem"></param>
        public void AddSubItem(StepItem subItem)
        {
            if (SubItems == null) SubItems = new List<StepItem>();

            SubItems.Add(subItem);
        }

        public bool HasSubItems
        {
            get { return SubItems != null && SubItems.Count > 0; }
        }

        public bool HasColor
        {
            get { return Color != null && Color.HasValue; }
        }

        public bool HasName
        {
            get { return !string.IsNullOrEmpty(Name); }
        }
    }

    public class STEPWriter
    {
        public static bool Write(IEnumerable<StepItem> items, string filename)
        {
            STEPWriter w = new STEPWriter();
            return w.WriteStepfile(items, filename);
        }

        public static bool Write(StepItem item, string filename)
        {
            return STEPWriter.Write(new StepItem[] { item }, filename);
          
        }

        OCTDocStd_Document _document;
        OCTDF_Label _mainLabel;
        OCXCAFDoc_ShapeTool _shapeTool;
        OCXCAFDoc_ColorTool _colorTool;

        private bool WriteStepfile(IEnumerable<StepItem> items, string filename)
        {
            _document = new OCTDocStd_Document(new OCTCollection_ExtendedString("DocType"));

            OCXCAFDoc_ShapeTool.SetAutoNaming(true);

            _mainLabel = _document.Main();
            _shapeTool = OCXCAFDoc_DocumentTool.ShapeTool(_mainLabel);
            _colorTool = OCXCAFDoc_DocumentTool.ColorTool(_mainLabel);

            foreach (StepItem stepItem in items)
            {
                AddItem(stepItem);
            }

            OCSTEPCAFControl_Writer writer = new OCSTEPCAFControl_Writer();
            writer.SetNameMode(true);
            writer.SetColorMode(true);
            writer.SetLayerMode(true);
            writer.SetPropsMode(true);
            writer.SetSHUOMode(true);

            writer.Transfer(_document, OCSTEPControl_StepModelType.STEPControl_AsIs);
            OCIFSelect_ReturnStatus ret = writer.Write(filename);
        
            return ret == OCIFSelect_ReturnStatus.IFSelect_RetDone;
        }

        private void AddItem(StepItem stepItem)
        {
            OCTDF_Label shapeLabel = _shapeTool.AddShape(stepItem.Shape, true, true);

            SetShapeLabel(shapeLabel, stepItem);
        }

        private void SetShapeLabel(OCTDF_Label shapeLabel, StepItem stepItem)
        {
            if (shapeLabel == null || shapeLabel.IsNull())
                return;

            OCXCAFDoc_ShapeMapTool shapeMap = OCXCAFDoc_ShapeMapTool.Set(shapeLabel);
            shapeMap.SetShape(stepItem.Shape);

            if (stepItem.HasName)
            {
                OCTDataStd_Name.Set(shapeLabel, new OCTCollection_ExtendedString(stepItem.Name));
            }

            if (stepItem.HasColor)
            {
                _colorTool.SetColor(shapeLabel, stepItem.Color.Value.ToOCCColor(), stepItem.ColorType);
                _colorTool.AddColor(stepItem.Color.Value.ToOCCColor());
                
            }

            if (stepItem.HasSubItems)
            {

                foreach (StepItem subStepItem in stepItem.SubItems)
                {
                    OCTDF_Label subShapeLabel = _shapeTool.AddSubShape(shapeLabel, subStepItem.Shape);
                    SetShapeLabel(subShapeLabel, subStepItem);
                }
            }
        }

    }
}

User code:

  /// <summary>
        //Write stepfile
        ///</summary>
        [TestMethod()]
        [TestCategory(TestCategories.OCC)]
        public void TestWriteStepfileWithColors()
        {
            OCTopoDS_Shape box = new OCBRepPrimAPI_MakeBox(2, 5, 6).Shape();
            StepItem shapeItem = new StepItem() { Shape = box, Name = "box" };

            List<OCTopoDS_Face> faces = box.Faces().ToList();

            Debug.Assert(faces.Count == 6);

            shapeItem.AddSubItem(new StepItem() { Name = "face0", Shape = faces[0], Color = Color.Blue });
            shapeItem.AddSubItem(new StepItem() { Name = "face1", Shape = faces[1], Color = Color.Green });
            shapeItem.AddSubItem(new StepItem() { Name = "face2", Shape = faces[2], Color = Color.Yellow });
            shapeItem.AddSubItem(new StepItem() { Name = "face3", Shape = faces[3], Color = Color.Red });
            shapeItem.AddSubItem(new StepItem() { Name = "face4", Shape = faces[4], Color = Color.Orange });
            shapeItem.AddSubItem(new StepItem() { Name = "face5", Shape = faces[5], Color = Color.Magenta });

            STEPWriter.Write(shapeItem, @"c:\test.step");

        }

Roman's picture

Thank you.
I meant the first option.
But there is one feature.
I create several TopoDS_Shape, then combined them into one.
TopoDS_Compound aRes;
BRep_Builder aBuilder;
aBuilder.MakeCompound (aRes);
aBuilder.Add (aRes, sBox); // First TopoDS_Shape
aBuilder.Add (aRes, sAxis); // Second TopoDS_Shape
In its sAxis line also consists of several TopoDS_Shape. (This is a local coordinate system in the domain).
And I need to set a different color for different axes, but to further the domain and the axis could be selected as a single object. Is it possible?
Thank you.

Guido van Hilst not specified's picture

This is possible, as follow.

The box and the local axis are now selectable as one compound.

But the edges of the local axis are colored.

  public void Test(OCAIS_InteractiveContext context)
        {

            OCgp_Pnt localOrigin= new OCgp_Pnt(2,5,8);
            OCgp_Dir dir = new OCgp_Dir(2,5,7);

            double axisLength=20.0;

            OCgp_Ax2 localAxis = new OCgp_Ax2(localOrigin, dir);

            OCgp_Pnt x1 = localOrigin.Translated(localAxis.XDirection().Multiply(axisLength));
            OCgp_Pnt y1 = localOrigin.Translated(localAxis.YDirection().Multiply(axisLength));
            OCgp_Pnt z1 = localOrigin.Translated(localAxis.Direction().Multiply(axisLength));

            OCTopoDS_Edge ex = new OCBRepBuilderAPI_MakeEdge(localOrigin, x1).Edge();
            OCTopoDS_Edge ey= new OCBRepBuilderAPI_MakeEdge(localOrigin, y1).Edge();
            OCTopoDS_Edge ez = new OCBRepBuilderAPI_MakeEdge(localOrigin, z1).Edge();

            OCAIS_Shape ais = new OCAIS_Shape(ex);
            ais.Attributes().SetWireAspect(new OCPrs3d_LineAspect(Color.Red.ToOCCColor(),  OCAspect_TypeOfLine.Aspect_TOL_SOLID,3));
            ais.SetSelectionMode(-1);
            context.Display(ais, false);

            ais = new OCAIS_Shape(ey);
            ais.Attributes().SetWireAspect(new OCPrs3d_LineAspect(Color.Green.ToOCCColor(), OCAspect_TypeOfLine.Aspect_TOL_SOLID, 3));
            ais.SetSelectionMode(-1);
            context.Display(ais, false);

            ais = new OCAIS_Shape(ez);
            ais.Attributes().SetWireAspect(new OCPrs3d_LineAspect(Color.Blue.ToOCCColor(), OCAspect_TypeOfLine.Aspect_TOL_SOLID, 3));
            ais.SetSelectionMode(-1);
            context.Display(ais, false);

            OCTopoDS_Compound aRes = new OCTopoDS_Compound();
            OCBRep_Builder aBuilder = new OCBRep_Builder();

            aBuilder.MakeCompound(aRes);

            aBuilder.Add(aRes, ex);
            aBuilder.Add(aRes, ey);
            aBuilder.Add(aRes, ez);

            OCTopoDS_Shape box = new OCBRepPrimAPI_MakeBox(5, 6, 7).Shape();
            OCgp_Trsf tr = new OCgp_Trsf();
            tr.SetDisplacement(new OCgp_Ax3(), new OCgp_Ax3(localAxis));
            box = new OCBRepBuilderAPI_Transform(box, tr).Shape();

            aBuilder.Add(aRes, box);

            ais = new OCAIS_Shape(aRes);
            ais.SetSelectionMode(0);
            ais.SetColor(Color.Gray.ToOCCColor());
            context.Display(ais, true);

        }

Attachments: 
Roman's picture

It is very good. Thank you very much.
A couple more questions. (I'm sorry I'm such a bore)
1) I translate this code into C ++ code (Handle (AIS_Shape) ais = new AIS_Shape (ex);) and found that the lack of a method
ais.SetSelectionMode (-1);
Do I understand correctly that this method does not select themselves the axis, but the object is selected?
You do not know what there is a similar method?
2) [offtop] How to draw the same grid as you?

//--- edit ---

Tell me more please, if you select a cube and remove it through a context, the axis must also remove?
I probably something not done, the axis of my stay.

//--- edit_2 ---

I added an additional function.
void DeleteAxis () {
myAISContext-> Erase (aisX);
myAISContext-> Erase (aisY);
myAISContext-> Erase (aisZ);
}
When the cube is removed, then this function is called.
Perhaps there is a better solution, but it still works well.

Guido van Hilst not specified's picture

The SetSelectionMode method is on AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)

Yes each Ais_InteractiveObjects that you have displayed should be explicitly Erased/Removed from the context if you don't want to show it anymore in the view.

For showing a grid in the view:

void SetGrid( OCV3d_Viewer viewer,OCgp_Ax3 aPlane)

{

  viewer.SetPrivilegedPlane(aPlane);
  viewer.SetRectangularGridGraphicValues(10, 10, 0.0);
  Viewer.SetRectangularGridValues(0,0, 5, 5, 0.0);
  OCAspect_GridDrawMode drawMode = OCAspect_GridDrawMode.Aspect_GDM_Lines
   Viewer.ActivateGrid(OCAspect_GridType.Aspect_GT_Rectangular, drawMode);

}

Roman's picture

Thank you.
The last question, and I'll leave you alone. Seriously =)
How to obtain the direction of each of the axes?
I create an object, but then in the process of the local system of coordinates can be changed.
How then get their direction?

Here is my code (the function takes the Description for the rotation in degrees):
void ShowAxisV2(double xAxis, double yAxis, double zAxis)
{
    gp_Pnt localOrigin(xMin, yMin, zMin);
    gp_Dir dir(0, 0, 1);

    double axisLength = ((Math::Abs(xMax - xMin) + Math::Abs(yMax - yMin) + Math::Abs(zMax - zMin)) / 3) / 3;

    gp_Ax2 localAxis(localOrigin, dir);
    gp_Pnt x1(localOrigin.Translated(gp_Vec(localAxis.XDirection()).Multiplied(axisLength)));
    gp_Pnt y1(localOrigin.Translated(gp_Vec(localAxis.YDirection()).Multiplied(axisLength)));
    gp_Pnt z1(localOrigin.Translated(gp_Vec(localAxis.Direction()).Multiplied(axisLength)));

    gp_Trsf myTrsf;

    TopoDS_Edge ex(BRepBuilderAPI_MakeEdge(localOrigin, x1).Edge());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(1., 0., 0.)), xAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform1(ex, myTrsf);
    ex = TopoDS::Edge(xform1.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 1., 0.)), yAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform2(ex, myTrsf);
    ex = TopoDS::Edge(xform2.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 0., 1.)), zAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform3(ex, myTrsf);
    ex = TopoDS::Edge(xform3.Shape());

    TopoDS_Edge ey(BRepBuilderAPI_MakeEdge(localOrigin, y1).Edge());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(1., 0., 0.)), xAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform4(ey, myTrsf);
    ey = TopoDS::Edge(xform4.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 1., 0.)), yAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform5(ey, myTrsf);
    ey = TopoDS::Edge(xform5.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 0., 1.)), zAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform6(ey, myTrsf);
    ey = TopoDS::Edge(xform6.Shape());

    TopoDS_Edge ez(BRepBuilderAPI_MakeEdge(localOrigin, z1).Edge());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(1., 0., 0.)), xAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform7(ez, myTrsf);
    ez = TopoDS::Edge(xform7.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 1., 0.)), yAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform8(ez, myTrsf);
    ez = TopoDS::Edge(xform8.Shape());
    myTrsf.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 0., 1.)), zAxis * M_PI / 180);
    BRepBuilderAPI_Transform xform9(ez, myTrsf);
    ez = TopoDS::Edge(xform9.Shape());

    Standard_Real aWidth = 3;

    aisX = new AIS_Shape(ex);
    Handle(Prs3d_LineAspect) wireRed = new Prs3d_LineAspect(Quantity_Color(Quantity_NOC_RED), Aspect_TypeOfLine::Aspect_TOL_SOLID, aWidth);
    aisX->Attributes()->SetWireAspect(wireRed);
    myAISContext->Display(aisX, false);

    aisY = new AIS_Shape(ey);
    Handle(Prs3d_LineAspect) wireGreen = new Prs3d_LineAspect(Quantity_Color(Quantity_NOC_GREEN), Aspect_TypeOfLine::Aspect_TOL_SOLID, aWidth);
    aisY->Attributes()->SetWireAspect(wireGreen);
    myAISContext->Display(aisY, false);

    aisZ = new AIS_Shape(ez);
    Handle(Prs3d_LineAspect) wireBlue = new Prs3d_LineAspect(Quantity_Color(Quantity_NOC_BLUE1), Aspect_TypeOfLine::Aspect_TOL_SOLID, aWidth);
    aisZ->Attributes()->SetWireAspect(wireBlue);
    myAISContext->Display(aisZ, false);
    
    // HERE TO GET DIRECTIONS AXES

    TopoDS_Compound aRes;
    BRep_Builder aBuilder;
    aBuilder.MakeCompound(aRes);
    aBuilder.Add(aRes, ex);
    aBuilder.Add(aRes, ey);
    aBuilder.Add(aRes, ez);

    TopoDS_Shape box = BRepPrimAPI_MakeBox(gp_Pnt(xMin, yMin, zMin), gp_Pnt(xMax, yMax, zMax)).Shape();
    aBuilder.Add(aRes, box);

    ais = new AIS_Shape(aRes);
    Quantity_Color colGray(Quantity_NOC_YELLOW);
    ais->SetColor(colGray);
    myAISContext->Display(ais, true);
}

If I could not explain. I added a screenshot.

Attachments: 
Guido van Hilst not specified's picture

Hi Roman,

I am not sure exactly what you mean. but I think you want to make a transformation for given three angles for each global axis(x,y,z)

I think that you can use: gp_Quaternion

​see topic http://www.opencascade.com/content/get-euler-angles-gptrsf-gpquaterniong...

If you specify the problem more formally I can write a code snipped..

Best regards,

Guido

Roman's picture

Oh ... the problem is that I do not know how to say it correctly.
Attached is another screenshot.
For example, when an object is created local and global coordinate systems are the same. X-axis has a direction (1, 0, 0), Z-axis direction is (0, 0, 1). But then I change the local Y-axis of the coordinate system 45 degrees, accordingly the direction of X and Z axes with respect to change of the global coordinate system and will be equal to: X-axis (0 0.707 -0.707), and Z-axis (0.707 0 0.707). I need to get a new direction axes.

I tried this code. But it doesn't work.

gp_Pnt localOrigin(xMin, yMin, zMin);
gp_Dir dir(0, 0, 1);

gp_Ax2 localAxis(localOrigin, dir);
gp_Pnt x1(localOrigin.Translated(gp_Vec(localAxis.XDirection()).Multiplied(axisLength)));
gp_Pnt y1(localOrigin.Translated(gp_Vec(localAxis.YDirection()).Multiplied(axisLength)));
gp_Pnt z1(localOrigin.Translated(gp_Vec(localAxis.Direction()).Multiplied(axisLength)));

gp_Trsf myTrsf1;
gp_Trsf myTrsf2;
gp_Trsf myTrsf3;

TopoDS_Edge ex(BRepBuilderAPI_MakeEdge(localOrigin, x1).Edge());
myTrsf1.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(1., 0., 0.)), xAxis * M_PI / 180);
BRepBuilderAPI_Transform xform1(ex, myTrsf1);
ex = TopoDS::Edge(xform1.Shape());
myTrsf2.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 1., 0.)), yAxis * M_PI / 180);
BRepBuilderAPI_Transform xform2(ex, myTrsf2);
ex = TopoDS::Edge(xform2.Shape());
myTrsf3.SetRotation(gp_Ax1(gp_Pnt(xMin, yMin, zMin), gp_Dir(0., 0., 1.)), zAxis * M_PI / 180);
BRepBuilderAPI_Transform xform3(ex, myTrsf3);
ex = TopoDS::Edge(xform3.Shape());

// Get New Direction
gp_Trsf myTrsfRes;
myTrsfRes = myTrsf1 * myTrsf2 * myTrsf3;
gp_Quaternion q = myTrsfRes.GetRotation();
xc = q.X();
yc = q.Y();
zc = q.Z();

Thank you. With respect, Roman.

Attachments: 
Roman's picture

Hey. It's me again.
Are there any suggestions for my last question?
Thank you.

Guido van Hilst not specified's picture

Hi Roman,

Is all about if you want to rotate on global coordinate or local?

Here is example to rotate an Axis3 in global coordinates for given 3 angles:

   public OCgp_Ax3 RotateGlobal(OCgp_Ax3 axIn, double angleRadX,double angleRadY,double angleRadZ)
        {

            OCgp_Ax3 axOut = new OCgp_Ax3(axIn);

            OCgp_Trsf rot = new OCgp_Trsf();

            rot.SetRotation(OCgp.OX(), angleRadX);
            axOut.Transform(rot);

            rot.SetRotation(OCgp.OY(), angleRadY);
            axOut.Transform(rot);

            rot.SetRotation(OCgp.OZ(), angleRadZ);
            axOut.Transform(rot);

            return axOut;

        }

If you want to rotate on the axIn replace "OCgp.OX()" by "new OCgp_Ax1(axIn.Location(), axIn.XDirection());"

Hope this is what you mean?

Roman's picture

Hooray! This is exactly what I need.
Everything works fine.
Thank you very much for giving me help.

Guido van Hilst not specified's picture

That is great :)

If I can help on anything else just let me know.