Exemple #1
0
        /// <summary>
        /// Load the iges format of the body from the stream
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static List <IBody2> LoadBodiesAsIges(Stream stream)
        {
            var igesFile = GetTempFilePathWithExtension(ExportGeometryFileExtension);

            LogViewer.Log($"Loading iges file {igesFile} into Solidworks");
            using (var ostream = File.OpenWrite(igesFile))
            {
                stream.CopyTo(ostream);
            }
            var doc = SwAddinBase.Active.SwApp.LoadIgesInvisible(igesFile);

            try
            {
                var newPartDoc = (PartDoc)doc;
                Debug.Assert(newPartDoc != null);

                var loadedBody =
                    newPartDoc.GetBodies2((int)swBodyType_e.swAllBodies, false).CastArray <IBody2>().ToList();
                Debug.Assert(loadedBody.Count > 0);

                return(loadedBody.Select(p => p.CopyTs()).ToList());
            }
            finally
            {
                SwAddinBase.Active.SwApp.QuitDoc(doc.GetTitle());
            }
        }
        public async Task CanRebuildSelected()
        {
            var modelDoc = (IModelDoc2)SwApp.ActiveDoc;

            var surface = modelDoc
                          .GetBodiesTs(swBodyType_e.swSolidBody)[0];

            // Copy the original surface
            var surfaceCopy = surface.CopyTs();

            // Temporarily hide the original surface so the model viewport is clear
            using (surface.HideBodyUndoable())
            {
                // Display the copy so the tester can visually verify it is ok.
                // Press "Continue Test Execution" button within solidworks
                // to continue the test after visual inspection of the sheet
                using (surfaceCopy.DisplayUndoable(modelDoc, Color.Green))
                    await PauseTestExecution();

                // The sheet should only have one face. Extract it
                IFace2[] faces
                    = surfaceCopy.GetFaces().CastArray <IFace2>();

                // Convert the solidworks face to our representation
                List <BSplineFace> bsplineFaces
                    = faces
                      .Select(BSplineFace.Create)
                      .ToList();

                var bsplineFacesJson = JsonConvert.SerializeObject(bsplineFaces, Formatting.Indented);

                // you can now paste this into your favorite editor
                copy_to_clipboard(bsplineFacesJson);

                LogViewer.Log("JSON of bsplineFaces is now in clipboard");

                // Convert our representation back to an IBody2. We
                // have used Option<T> wrappers to indicate failure
                // or success for each conversion.
                List <Option <IBody2> > faceBodies
                    = bsplineFaces
                      .Select(bsplineFace => bsplineFace.ToSheetBody())
                      .ToList();

                // Count the number of faces that were not able to
                // be converted from bspline surface to IBody2
                int numberOfBadFaces = faceBodies.Count(b => b.IsNone);
                LogViewer.Log($"Number of bad faces is {numberOfBadFaces}");

                // Display the recovered sheet. Visually verify it is ok
                // Press "Continue Test Execution" button within solidworks
                // to continue the test after visual inspection of the sheet
                using (faceBodies.WhereIsSome().DisplayUndoable(modelDoc, Color.Blue))
                    await PauseTestExecution();


                // Assert that the test has passed.
                numberOfBadFaces.Should().Be(0);
            }
        }
Exemple #3
0
 private void Redraw()
 {
     try
     {
         _ModelView.GraphicsRedraw(null);
     }
     catch (COMException e)
     {
         LogViewer.Log($"Exception was expected '{e.Message}' but logging it anyway");
     }
 }
        public static BSpline3D ToBSpline3D(this SplineParamData swSurfParameterisation, bool isClosed)
        {
            object ctrlPts;
            var    canGetCtrlPts = swSurfParameterisation.GetControlPoints(out ctrlPts);

            Debug.Assert(canGetCtrlPts);
            var ctrlPtArray = ctrlPts.CastArray <double>();

            object knots;
            var    canGetKnots = swSurfParameterisation.GetKnotPoints(out knots);

            Debug.Assert(canGetKnots);
            var knotArray = knots.CastArray <double>();

            var dimension = swSurfParameterisation.Dimension;
            var order     = swSurfParameterisation.Order;
            var degree    = order - 1;

            var isPeriodic = swSurfParameterisation.Periodic == 1;

            var controlPoints4D = ctrlPtArray
                                  .Buffer(dimension, dimension)
                                  .Where(p => p.Count == dimension)
                                  //http://help.solidworks.com/2016/english/api/sldworksapi/solidworks.interop.sldworks~solidworks.interop.sldworks.isplineparamdata~igetcontrolpoints.html
                                  .Select
                                      (p =>
            {
                var x = 0.0;
                var y = 0.0;
                var z = 0.0;
                var w = 1.0;
                if (dimension >= 2)
                {
                    x = p[0];
                    y = p[1];
                }
                if (dimension >= 3)
                {
                    z = p[2];
                }
                if (dimension == 4)
                {
                    w = p[3];
                }

                return(new Vector4(x * w, y * w, z * w, w));
            })
                                  .ToArray();

            if (controlPoints4D.Any(c => c.W != 1.0))
            {
                LogViewer.Log($"Got a rational curve, periodic = {isPeriodic}, isClosed = {isClosed}");
            }

            if (isPeriodic)
            {
                ConvertToNonPeriodic(ref controlPoints4D, ref knotArray, degree);
            }

            return(new BSpline3D(controlPoints4D, knotArray, order, isClosed: isClosed, isRational: dimension == 4));
        }
        /// <summary>
        /// Create a BSplineFace from the TrimCurve data.
        /// http://help.solidworks.com/2015/English/api/sldworksapi/SOLIDWORKS.Interop.sldworks~SOLIDWORKS.Interop.sldworks.IFace2~GetTrimCurves2.html
        /// </summary>
        /// <param name="swFace"></param>
        /// <returns></returns>
        public static BSplineFace Create(IFace2 swFace)
        {
            var start = 0;

            var packedData = swFace.GetTrimCurves2(WantCubic: true, WantNRational: false).CastArray <double>();
            var reader     = new GetTrimCurves2DataReader(packedData);

            // Packed Double 1
            // An integer pair containing number of loops and total number of SP curves (trim curves).
            // The length of any edge list generated immediately after a call to IFace2::GetTrimCurves2
            // will be equal to the number of SP curves
            var packedDouble1 = reader.ReadDouble().DoubleToInteger();
            int numLoops      = packedDouble1.Item1;
            int numSPCurves   = packedDouble1.Item2;

            // PackeDouble 2
            // Series of integer pairs containing the number of SP curves in each loop.
            // The first integer in each pair represents the number of curves in the odd loops;
            // the second represents the even. The total number of integer pairs is half the
            // number of loops, rounded up
            var curvesPerLoopLookup = reader.ReadIntegers(numLoops).ToList();

            var i = 0;

            // PackedDouble 3[]  ( Array of doubles )
            // For each SP curve, a set of two integer pairs.
            // The first contains the order of the curve and
            // a Boolean indicating if it is periodic.If the curve is periodic,
            // it is clamped (that is, knots of multiplicity = order exists at each end of the curve).
            // The second contains the dimension of the curve and the number of control points in it.
            // If the dimension is 2, then the curve is non - rational; if the dimension is 3,
            // then the curve is rational.
            var spCurveInfos = reader
                               .ReadBufferedIntegers(bufferSize: 4, numberOfBuffers: numSPCurves)
                               .Do(b =>
            {
                LogViewer.Log($"Get TrimCurves2 'PackedDouble 3' buffer {i++}");
                LogViewer.Log(string.Join(" ", b));
            })
                               .Select(b => new { order = b[0], isPeriodic = b[1] == 1, dimension = b[2], isRational = b[2] == 3, numCtrlPoints = b[3] })
                               .ToList();

            var spCurveInfos2 = spCurveInfos
                                .Select
                                    (info =>
            {
                var knots = reader.Read(info.order + info.numCtrlPoints).ToList();
                return(new { info.order, info.isPeriodic, info.dimension, info.isRational, info.numCtrlPoints, knots });
            })
                                .ToList();

            var trimCurves = spCurveInfos2
                             .Select
                                 (info =>
            {
                var ctrlPoints = reader
                                 .Read(info.numCtrlPoints * info.dimension)
                                 .Buffer(info.dimension, info.dimension)
                                 .Select(ToRationalVector3)
                                 .ToList();

                return(new BSpline2D
                           (controlPoints: ctrlPoints.ToArray()
                           , knotVectorU: info.knots.ToArray()
                           , order: info.order
                           , isClosed: info.isPeriodic
                           , isRational: info.dimension == 3));
            })
                             .ToArray();


            var bLoops = curvesPerLoopLookup
                         .Scan(new { start = 0, step = 0 }, (acc, count) => new { start = acc.start + acc.step, step = count })
                         .Skip(1)
                         .Select(o => trimCurves.ToArraySegment(o.start, o.step).ToArray())
                         .ToArray();


            fixLoops(bLoops);

            // packed double 4
            var surfaceDimension = reader.ReadDouble().DoubleToInteger().Item1;

            // packed double 5
            var uvOrder = reader.ReadDouble().DoubleToInteger().Map((u, v) => new { u, v });

            // packed double 6
            var uvNumCtrlPoints = reader.ReadDouble().DoubleToInteger().Map((u, v) => new { u, v });

            // packed double 7
            var uvIsPeriodic = reader.ReadDouble().DoubleToInteger().Map((u, v) => new { u, v });

            // surfaceKnotValuesU
            var uKnots = reader.Read(uvOrder.u + uvNumCtrlPoints.u).ToArray();

            // surfaceKnotValuesV
            var vKnots = reader.Read(uvOrder.v + uvNumCtrlPoints.v).ToArray();

            // surfaceCtrlPoinCoords
            var surfaceCtrlPoints = reader.Read(surfaceDimension * uvNumCtrlPoints.u * uvNumCtrlPoints.v)
                                    .Buffer(surfaceDimension, surfaceDimension)
                                    .Select(ToRationalVector4WithWeighRescaling)
                                    .ToList();

            // packed doubles 8
            // TODO handle the case for multiple surfaces
            var indexFlags = reader.ReadDouble().DoubleToInteger().Map((nSurface, index) => new { nSurface, index });

            var ctrlPointsArray = surfaceCtrlPoints.Reshape(uvNumCtrlPoints.u, uvNumCtrlPoints.v);

            var bSurface = new BSplineSurface(ctrlPointsArray, uvOrder.u, uvOrder.v, uKnots, vKnots, surfaceDimension, uvIsPeriodic.u == 1, uvIsPeriodic.v == 1);

            return(new BSplineFace(bSurface, bLoops));
        }