Invalid Brep after Transform

Hi to all,

I have problem with forming invalid Brep after some transformations.Here is my code for checking:

 bool isValidONXF=modelTransform.IsValid(); // ON_Xform is valid
 ON_BrepPtr brep = models.at(j)->mBreps.at(k);
 bool transfSucc = brep->Transform(modelTransform); // transformation is successful
 bool brepAfterTransformatio=brep->IsValid(); // brep is invalid after transformation

I see that transformations as well as ON_Xform matrix is valid but after brep transform it become invalid. Could you please help me why is this happening and what may be error in this situation (Brep or ON_Xform) and how I can transform Brep correctly.

Thanks a lot,
Best regards,
Iv

Hi @Ivi,

To be of assistance, we’re going to need to see the Brep and the code behind the transformation so we can repeat what you are seeing.

– Dale

Hi Dale,

Here is my code with transformation and in addition is model brep.

  const wchar_t* file = L"C:\\Users\\user\\Desktop\\InvaliBrep.3dm";
    FILE* archive_fp = ON::OpenFile(file,L"rb");
 
    ON_BinaryFile archive(ON::read3dm, archive_fp);
    ON_TextLog error_log;
    ONX_Model model;
    bool result = model.Read(archive, &error_log);
    std::vector<ON_BrepPtr> breps; // file may consist from multiple breps

    for (int i = 0;i < model.m_object_table.Count();i++)
    {
        const ON_Object* obj = 0;
        ONX_Model_Object* object = model.m_object_table.At(i);
        THROWX(object != NULL, "Error reading object from opennurbs table. ");
        obj = object->m_object;
        ON_Object* non = const_cast<ON_Object*>(obj);    
        ON_Brep* bObj = dynamic_cast<ON_Brep*>(non);

        if (bObj != NULL)
        {
            THROWX(bObj->IsValid(), "The brep is not valid!"); // check brep validity before transform

            ON_BrepPtr bPtr(bObj->Duplicate());
            breps.push_back(bPtr);
        }
    }
  
   // transformation for suitable Brep
    ON_Xform transform;
    transform[0][0] = 1;
    transform[0][1] = 0;
    transform[0][2] = 0;
    transform[0][3] = -1719.99;

    transform[1][0] = 0;
    transform[1][1] = 0.9999;
    transform[1][2] = 0;
    transform[1][3] = 407.2624;

    transform[2][0] = 0;
    transform[2][1] = 0;
    transform[2][2] = 1;
    transform[2][3] = 1703.999;

    transform[3][0] = 0;
    transform[3][1] = 0;
    transform[3][2] = 0;
    transform[3][3] = 1;

    for (int b = 0; b < breps.size(); b++)
    {
        ON_BrepPtr brep = breps.at(b);
        bool isSuccTran=brep->Transform(transform);
        bool isValidAfterTran=brep->IsValid(); // in this case brep is invalid
    }

Thanks a lot,
Iv
InvaliBrep.3dm (1.1 MB)

Hi @Ivi,

Why is this important?

xform[1][1] = 0.9999;

A translation transformation should look like this:

1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1

We recommend construction translation transformations using ON_Xform::Translation.

– Dale

Actually I get transform matrix from debugger and put the same values in my test sample to get the same result invalid brep…

I think that I solve my problem. First I create transformation from other library (combination of rotation and translation) and put transformation matrix directly to ON_Xform. Library works with float values, instead ON_Xform works with double which I think I lose some precision during casting process. In this case on debugger i have transformation as was written previously (with xForm[1][1]=0.999). As a result of your recommendation Dale I use ON_Xform step by step with functions Translation and Rotation using double for angles and suitable axis and rotation center. After these step by step transformation there is no Invalid Brep :slight_smile:

Thanks a lot for help Dale :smiley: