-2

C++ メソッドは、条件付きブレークポイントを使用すると正しい値を返しますが、ブレークポイントがない場合は正しくない値を返します。

C++ を呼び出す C# メソッド:

bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
{
        // Loop over STLs
        for (int i = 0; i < materializers.Count; i++)
        {               
            Materializer materializer = materializers[i];

            if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeDatasets[i].top))
            {
                element.PropertyId = properties[i];
                return true;
            };
        }
        return false;
    }

ヘッダー ファイルの C++ メソッド:

    int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
    {
        Math3d::M3d rayPoints[2], intersectionPoint;

        rayPoints[0].set(x,y,z);
        rayPoints[1].set(x,y,1.0e6);

        if(!root) 
            return 0;
        else
        {
            int special = CountIntersects(x,y,z,root->special);
            if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
            {       
                if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
                {
                    return (1 + special);
                }
                else 
                    return special;
            }
            else
            {
             if (y>root->yMax)
                 {
                    return (CountIntersects(x,y,z,root->top)+special);
              }
              else if(y<root->yMin)
                    {
                        return (CountIntersects(x,y,z,root->bottom)+special);
                    }
                    else if(x<root->xMin)
                            {
                                return (CountIntersects(x,y,z,root->left)+special);
                            }
                            else if(x>root->xMax)
                            {
                                return (CountIntersects(x,y,z,root->right)+special);
                            }
                            else 
                                return special;
            }
        }
    }

    bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
    {
        int intersectionCount = 0;

        Math3d::M3d rayPoints[2], intersectionPoint;

        rayPoints[0].set(x,y,z);
        rayPoints[1].set(x,y,1.0e6);


        if(_box->IsContainingPoint(x,y,z))
        {           
            intersectionCount=CountIntersects(x,y,z,root);
            return (intersectionCount%2!=0);

        }   
    }

他のヘッダー ファイルの C++ メソッド:

    bool IsRayIntersectsPoly(int nPolygonIndex, Math3d::M3d RayPoints[2], CVector3D& IntersectionPoint)
{
    CMeshPolygonBase& Poly = m_PolygonArray[nPolygonIndex];
    CArrayResultI Result;

    int* pPolygonPoints = GetPolygonPoints(Poly, Result);

    Math3d::MPlane TrianglePlane;

    double Atmp[3], A;

    CVector3D* pPoints[3];
    pPoints[0] = &m_PointArray[*pPolygonPoints].m_Position;

    for(int i = 1; i < Result.GetSize() - 1; i++)
    {
        pPoints[1] = &m_PointArray[*(pPolygonPoints+i)].m_Position;
        pPoints[2] = &m_PointArray[*(pPolygonPoints+i+1)].m_Position;

        TrianglePlane.Init(*pPoints[0], *pPoints[1], *pPoints[2]);
        TrianglePlane.IntersectLine(RayPoints[0], RayPoints[1], IntersectionPoint);

        A = GetTriangleArea(*pPoints[0], *pPoints[1], *pPoints[2]);
        for(int j = 0; j < 3; j++)
        {
            Atmp[j] = GetTriangleArea(*pPoints[j], *pPoints[(j+1)%3], IntersectionPoint);
        }

        if( fabs(A - Atmp[0] - Atmp[1] - Atmp[2]) < 1.0e-5 ) return true;
    }

    return false;
};


    double GetTriangleArea(CVector3D& T1, CVector3D& T2, CVector3D& T3)
{
    double a, b, c, s;

    a = (T1 - T2).length();
    b = (T2 - T3).length();
    c = (T3 - T1).length();

    s = 0.5 * (a + b + c);

    return( sqrt(s * (s - a)* (s - b)* (s - c)) );
}

SetProperty()for ループ内で呼び出すプログラムを開始すると、一部のイテレータ値の結果が正しくありません。for ループの重要なイテレータ値に条件付きブレークポイントを設定してステップ オーバーすると、その項目の結果は OK です。何が問題なのですか?

これは、ブレークポイントを投稿する方法です。たとえば、重要な要素の場合.Id==2393.

 private void StartButton_Click(object sender, EventArgs e)
    {
        DateTime startTime = DateTime.Now;

        List<Materializer> materializers = new List<Materializer>();
        List<ulong> properties = new List<ulong>();

        // Load STLs
        for (int i = 0; (int)i < (this.dataGridView.RowCount - 1); i++)
        {
            if (dataGridView.Rows[i].Cells[1].Value != null && (string)dataGridView.Rows[i].Cells[1].Value != "")
            {
                Materializer materializer = new Materializer();
                materializer.LoadSTLMesh(dataGridView.Rows[i].Cells[0].Value.ToString());
                materializers.Add(materializer);
                properties.Add((ulong)dataGridView.Rows[i].Cells[1].Tag);                
            }
         }

        CreatePentalTrees(materializers);
        int processedElementCount = 0;
        int changedElementCount = 0;

        // Loop over elements
        foreach (Element element in model.ElementsList.Values)

            if ((element.Topology == 7 || element.Topology == 8) && !lockedProperties.ContainsKey(element.PropertyId)) // 3D elements only
            {


                Node center = this.CenterPoint(element, model.NodesList);

                if (element.Id == 2393)
                {
                    //if breakpoints thats ok, else not ok
                    Console.WriteLine(element.Id);
                    Console.WriteLine(element.PropertyId);
                }

                if (SetProperty(element, center, materializers, properties))   // Check for center point
                {
                    //changedElements.Add(element.Id, true);
                    changedElementCount++;
                }
                else
                {
                    // Check for all nodes if center point does not belong to any STL

                    int[] nodeOrder;

                    switch (element.Topology)
                    {
                        case 7:
                            nodeOrder = wedgeNodeOrder;
                            break;
                        case 8:
                            nodeOrder = brickNodeOrder;
                            break;
                        default:
                            throw new Exception("Unknown topology " + element.Topology.ToString());
                    }

                    for (int i = 0; i < nodeOrder.Length; i++)
                    {
                        Node node = model.NodesList[element.NodeIds[nodeOrder[i]]];

                        if (SetProperty(element, node, materializers, properties))
                        {
                            //changedElements.Add(element.Id, true);
                            changedElementCount++;
                            break;
                        }
                    }
                }

                if (++processedElementCount % 100 == 0)
                {
                    labelTime.Text = "Changed/processed elements: " + changedElementCount.ToString() + "/" + processedElementCount.ToString();
                    labelTime.Refresh();
                    Application.DoEvents();
                }

            }

        DateTime endTime = DateTime.Now;
        labelTime.Text = "Total time: " + (endTime - startTime).TotalSeconds.ToString() + " s";

        MessageBox.Show("Completed.");

        SaveFileDialog saveFileDlg = new SaveFileDialog();
        saveFileDlg.Title = "Save FEMAP neutral file";
        saveFileDlg.Filter = "(*.neu)|*.neu";
        if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            FemapNeutral.ExportNeu(saveFileDlg.FileName, model);
        }

    }
4

1 に答える 1

0

あなたがリストしていない多くのメソッドを呼び出しているようです、および/またはコードの壁が私を迷子にさせました。そのコードを追加しても役に立ちません。問題をより単純なものに減らして、問題の可能性を示します。

ただし、マネージ データを読み取るアンマネージ コードがある場合、問題の原因として最も可能性が高いのは、マネージ コードを使用する前にデータをマーシャリングまたはピン留めできなかったことです。

ピン留めされていないデータは、ガベージ コレクターによって予期しない方法で移動される可能性があります。

于 2013-08-09T18:43:45.353 に答える