Hi Toshi,
Thank you for referring to the A3DSurfEvaluateNormal API. I attempted to implement it, but unfortunately, it’s not working as expected.
I have included a sample of my code in the FeatureRecognitionDlg. I believe I might be getting confused about how to correctly pass arguments to the A3DSurfEvaluateNormal function (I am trying to get the normal vector of the selected, and all detected faces):
// Normal Vector Function
void FeatureRecognitionDlg::NormalVectors(A3DTopoFace* pSelTopoFace, std::vector<A3DEntity*>& pEntityArr)
{
    A3DStatus status;
    A3DTopoFaceData faceData;
    A3D_INITIALIZE_DATA(A3DTopoFaceData, faceData);
    // Retrieve face data for selected face
    status = A3DTopoFaceGet(pSelTopoFace, &faceData);
    if (status != A3D_SUCCESS)
    {
        CString errorMessage;
        errorMessage.Format(L"Failed to get face data for selected face: Error code %d", status);
        AfxMessageBox(errorMessage);
        return;
    }
    // Retrieve UV parameters from face data
    A3DVector2dData uvParameter;
    uvParameter.m_dX = (faceData.m_sSurfaceDomain.m_sMin.m_dX + faceData.m_sSurfaceDomain.m_sMax.m_dX) / 2.0;
    uvParameter.m_dY = (faceData.m_sSurfaceDomain.m_sMin.m_dY + faceData.m_sSurfaceDomain.m_sMax.m_dY) / 2.0;
    A3DVector3dData normal;
    A3D_INITIALIZE_DATA(A3DVector3dData, normal);
    // Evaluate normal for the selected face
    status = A3DSurfEvaluateNormal((const A3DSurfBase*)pSelTopoFace, &uvParameter, &normal);
    if (status == A3D_SUCCESS)
    {
        CString message;
        message.Format(L"Selected Face Normal: X: %f, Y: %f, Z: %f", normal.m_dX, normal.m_dY, normal.m_dZ);
        AfxMessageBox(message);
    }
    else
    {
        CString errorMessage;
        errorMessage.Format(L"Failed to evaluate normal for selected face: Error code %d", status);
        AfxMessageBox(errorMessage);
    }
    // Evaluate normal for each detected face
    for (size_t i = 0; i < pEntityArr.size(); ++i)
    {
        A3DTopoFace* pTopoFace = (A3DTopoFace*)pEntityArr[i];
        // Retrieve face data for detected face
        A3DTopoFaceData detectedFaceData;
        A3D_INITIALIZE_DATA(A3DTopoFaceData, detectedFaceData);
        status = A3DTopoFaceGet(pTopoFace, &detectedFaceData);
        if (status != A3D_SUCCESS)
        {
            CString errorMessage;
            errorMessage.Format(L"Failed to get face data for detected face %zu: Error code %d", i, status);
            AfxMessageBox(errorMessage);
            continue;
        }
        // Retrieve UV parameters from detected face data
        uvParameter.m_dX = (detectedFaceData.m_sSurfaceDomain.m_sMin.m_dX + detectedFaceData.m_sSurfaceDomain.m_sMax.m_dX) / 2.0;
        uvParameter.m_dY = (detectedFaceData.m_sSurfaceDomain.m_sMin.m_dY + detectedFaceData.m_sSurfaceDomain.m_sMax.m_dY) / 2.0;
        status = A3DSurfEvaluateNormal((const A3DSurfBase*)pTopoFace, &uvParameter, &normal);
        if (status == A3D_SUCCESS)
        {
            CString message;
            message.Format(L"Detected Face %zu Normal: X: %f, Y: %f, Z: %f", i, normal.m_dX, normal.m_dY, normal.m_dZ);
            AfxMessageBox(message);
        }
        else
        {
            CString errorMessage;
            errorMessage.Format(L"Failed to evaluate normal for detected face %zu: Error code %d", i, status);
            AfxMessageBox(errorMessage);
        }
    }
}
Then I tried to call NormalVectors(…) in the OnTimer(…) under Exchange part. It seems that the it is not being called here properly as I checked with debug text messages, or it may not be the right place to call it.
#ifdef USING_EXCHANGE_PARASOLID
            selFace = ((HPS::Parasolid::Component)selCompArr[0]).GetParasolidEntity();
            HPS::Component bodyComp = view->GetOwnerPSBodyCompo(selCompArr[0]);
            PK_BODY_t body = ((HPS::Parasolid::Component)bodyComp).GetParasolidEntity();
            std::vector<PK_ENTITY_t> pkEntityArr;
            if (m_pProcess->FR((PsFRType)m_iFRType, selFace, pkEntityArr))
            {
                for (int i = 0; i < pkEntityArr.size(); i++)
                {
                    PK_FACE_t face = pkEntityArr[i];
                    if (selFace != face)
                    {
                        // Highlight face
                        HPS::Component comp = view->GetPsComponent(body, face);
                        highlightCompArr.push_back(comp);
                        // Show list box
                        CString sEnt;
                        sEnt.Format(_T("%d"), pkEntityArr[i]);
                        m_detectedFaceListBox.AddString(sEnt);
                    }
                }
            }
#else
            // Get owner BrepModel
            HPS::Component ownerComp = view->GetOwnerBrepModel(selCompArr[0]);
            A3DRiBrepModel* pRiBrepModel = HPS::Exchange::Component(ownerComp).GetExchangeEntity();
            A3DTopoFace* pSelTopoFace = HPS::Exchange::Component(selCompArr[0]).GetExchangeEntity();
            selFace = m_pProcess->GetEntityTag(pRiBrepModel, pSelTopoFace);
            std::vector<A3DEntity*> pEntityArr;
            if (m_pProcess->FR((PsFRType)m_iFRType, pRiBrepModel, pSelTopoFace, pEntityArr))
            {
                // Get component from selected A3DEntity
                HPS::Exchange::CADModel cad_model = view->GetDocument()->GetCADModel();
                for (int i = 0; i < pEntityArr.size(); i++)
                {
                    A3DEntity* pEntity = pEntityArr[i];
                    if (pSelTopoFace != pEntity)
                    {
                        HPS::Component comp = cad_model.GetComponentFromEntity(pEntity);
                        highlightCompArr.push_back(comp);
                        // Show list box
                        int iEnt = m_pProcess->GetEntityTag(pRiBrepModel, pEntity);
                        CString sEnt;
                        sEnt.Format(_T("%d"), iEnt);
                        m_detectedFaceListBox.AddString(sEnt);
                    }
                }
            }
            // Evaluate and display the normal vector
            NormalVectors(pSelTopoFace, pEntityArr);
#endif
            m_iSelFace = selFace;
            m_selectedFaceID = selFace; // Store the selected face ID
Could you please take a look at the code? I would sincerely appreciate it if you could point out the mistakes and guide me with the corrected code if possible.
Thank you very much again, for all your time.
Kazi